home *** CD-ROM | disk | FTP | other *** search
/ Eagles Nest BBS 8 / Eagles_Nest_Mac_Collection_Disc_8.TOAST / Developer Tools⁄Additions / UFullTEView / UFullTEView.inc1.p < prev    next >
Text File  |  1990-10-18  |  115KB  |  4,029 lines

  1.                         { UFullTEView Version 2.3 }
  2.                         
  3. { ******** This is MacApp 2.0 Final !!!! Do NOT use with 2.0ß9 !!!! *******    }
  4.  
  5. { Note to those who abhor special cases: This is not necessarily a unit whose     }
  6. {                                          code you really want to study at length.}
  7.  
  8. {$IFC MenuAccess}
  9. CONST
  10.  
  11.     kSubFont  =        FALSE;  { Is "Font" a hierarchical submenu? }
  12.     kSubSize  =     FALSE;  { Is "Size" a hierarchical submenu? }
  13.     kSubStyle =     FALSE;  { Is "Style" a hierarchical submenu? }
  14.     kSubJust  =     FALSE;  { Is "Justification" a hierarchical submenu? }
  15.         
  16.     cSizeChange =    3100;                { Font-size commands }
  17.     cSizeBase    =    3100;
  18.                   {    3101-3297 reserved for font sizes 1-197 pts. }
  19.     cSizeNextUp    =     3298;
  20.     cSizeNextDown=     3299;
  21.     cSizeMin    =    3109;    { Minimum size listed in menu is 9  }
  22.     cSizeMax    =    3124;    { Maximum size listed in menu is 24 }
  23.  
  24.     { Command numbers to cover other stylistic changes }
  25.     cJustChange =     3300;
  26.     cFontChange =     3400;
  27.  
  28.     { Command numbers for the hierarchial menus, if present }
  29.     cStyle        =     3501;
  30.     cSize        =     3502;
  31.     cFont        =     3503;
  32.     
  33.     cJustLeft    =     3608;    { Justification commands }
  34.     cJustCenter =     3609;
  35.     cJustRight    =     3610;
  36.  
  37.     { Constants for relative text resizing }
  38.     kSizeNextUp    =     1;
  39.     kSizeNextDown =    -1;
  40.     kRelSizeDelta =    4;
  41.     
  42.     { Cursor for italic text }
  43.     kSlantBeam    =    3001;
  44.  
  45. {$ENDC} {MenuAccess}
  46.     
  47. {--------------------------------------------------------------------------------------------------}
  48. {$IFC qDebug & SubSuper}
  49. {$S TENonRes}
  50.  
  51. PROCEDURE WrtSubSuperHandle(theSubSuperHandle: subSuperHandle);
  52.  
  53.     VAR        i:        INTEGER;
  54.  
  55.     PROCEDURE WrtSubSuper(num: INTEGER; theSubSuper: SubSuperElement);
  56.     
  57.         BEGIN
  58.         WITH theSubSuper DO
  59.             WriteLn('Index: ', num, '  startChar: ', startChar, 
  60.                                     '  subSuper: ', ORD(subSuper),
  61.                                     '  baseSize: ', baseSize);
  62.         END;
  63.  
  64.     BEGIN
  65.     IF theSubSuperHandle = NIL THEN EXIT(WrtSubSuperHandle);
  66.     MoveHHi(Handle(theSubSuperHandle));
  67.     HLock(Handle(theSubSuperHandle));
  68.     WrLblHexLongint('SubSuperHandle', Ord(theSubSuperHandle));
  69.     WITH theSubSuperHandle^^ DO
  70.         BEGIN
  71.         WriteLn(' nRuns: ', nRuns);
  72.         WriteLn('   nullSubSuper: ', ORD(nullSubSuper), '   nullBaseSize: ', nullBaseSize);
  73.         FOR i := 0 TO nRuns DO
  74.             WrtSubSuper(i, runs[i])
  75.         END;
  76.     HUnlock(Handle(theSubSuperHandle));
  77.     END;
  78.  
  79. {$ENDC}
  80. {--------------------------------------------------------------------------------------------------}
  81. {$S TEInit}
  82.  
  83. PROCEDURE InitUFullTEView;
  84.  
  85.     BEGIN
  86.     
  87.     InitUTEView;
  88.     
  89.     IF gDeadStripSuppression THEN
  90.         BEGIN
  91.         IF Member(TObject(NIL), TFullTEView) THEN;
  92.         {$IFC SubSuper}
  93.         IF Member(TObject(NIL), TFullSubSuperTEView) THEN;
  94.         {$ENDC}
  95.         END;
  96.         
  97.     {$IFC NOT qNeedsScriptManager}
  98.     IF gConfiguration.hasScriptManager THEN    
  99.     {$ENDC}
  100.     
  101.         gNoScripts := GetEnvirons(smEnabled) <= 1
  102.         
  103.     {$IFC NOT qNeedsScriptManager}
  104.     ELSE
  105.         gNoScripts := TRUE
  106.     {$ENDC};
  107.     
  108.     gFullWordLeft := FALSE;
  109.     gFullWordRight := FALSE;
  110.  
  111.     END;
  112.  
  113. {--------------------------------------------------------------------------------------------------}
  114. {$IFC MenuAccess}
  115. {$S TEOpen}
  116. {$PUSH}{$IFC qTRACE}{$D+}{$ENDC}
  117.  
  118. PROCEDURE DrawCaretProc; External;
  119.  
  120. PROCEDURE DrawHighProc; External;
  121.  
  122. PROCEDURE InstallSlant(theTEHdl: TEHandle);
  123.  
  124.     BEGIN
  125.     theTEHdl^^.caretHook := @DrawCaretProc;
  126.     theTEHdl^^.highHook := @DrawHighProc;
  127.     END;
  128.  
  129.  
  130. FUNCTION IsItalic(thePt: Point; theTEPtr: TEPtr): BOOLEAN;
  131.  
  132.     VAR        pos:            INTEGER;
  133.             theStyle:        TextStyle;
  134.             lineHeight:        INTEGER;
  135.             fontAscent:        INTEGER;
  136.             theStyleHandle:    TEStyleHandle;
  137.             theFullTEView:    TFullTEView;
  138.             theVPt:            VPoint;
  139.  
  140.     BEGIN
  141.     theStyleHandle := GetStylHandle(TEHandle(@theTEPtr));
  142.     
  143.     IF theStyleHandle <> NIL THEN
  144.         BEGIN
  145.         theFullTEView := TFullTEView(theStyleHandle^^.teRefCon);
  146.     
  147.         IF thePt.v < 0 THEN        { compensates for TEGetOffset bug on IIfx's }
  148.             pos := -1
  149.         ELSE
  150.             pos := TEGetOffset(thePt, TEHandle(@theTEPtr)) -1;    { Assumes System 4.1 or greater! }
  151.  
  152.         IF pos < 0 THEN
  153.             IsItalic := FALSE
  154.         ELSE
  155.             BEGIN
  156.             TEGetStyle(pos, theStyle, lineHeight, fontAscent, TEHandle(@theTEPtr));
  157.             IsItalic := italic IN theStyle.tsFace;
  158.             END
  159.         END
  160.     ELSE
  161.         IsItalic := italic IN theTEPtr^.txFace;
  162.     END;
  163.  
  164. {$POP}
  165. {$ENDC}
  166. {--------------------------------------------------------------------------------------------------}
  167. {$S TEOpen}
  168.  
  169. PROCEDURE TFullTEView.ITEView(itsDocument: TDocument; itsSuperView: TView; itsLocation, itsSize: VPoint;
  170.                           itsHDeterminer, itsVDeterminer: SizeDeterminer; itsInset: Rect;
  171.                           itsTextStyle: TextStyle; itsJustification: INTEGER; itsStyleType,
  172.                           itsAutoWrap: BOOLEAN); OVERRIDE;
  173.  
  174.     VAR        theStyleHandle:        TEStyleHandle;
  175.  
  176.     BEGIN
  177.  
  178. {$IFC SubSuper}
  179.     fFullTypingCommand := NIL;
  180.     fAllowSubSuper := FALSE;    {cannot use Subscript/Superscript menu commands}
  181.     fSubSuperHandle := NIL;
  182. {$ENDC}
  183.  
  184.     INHERITED ITEView(itsDocument, itsSuperView, itsLocation, itsSize,
  185.                         itsHDeterminer, itsVDeterminer, itsInset, itsTextStyle,
  186.                         itsJustification, itsStyleType, itsAutoWrap);
  187.     InstallSlant(fHTE);
  188.     fSelAnchor := fHTE^^.selStart;
  189.     fUpDown := FALSE;
  190.     
  191. {$IFC MenuAccess}
  192.     fMenuFont := TRUE;            {can use Font menu commands}
  193.     fMenuSize := TRUE;            {can use Size menu commands}
  194.     fMenuStyle := TRUE;            {can use Style menu commands}
  195.     fMenuJust := FALSE;            {cannot use Justification menu commands}
  196.     fMenuUpDown := fMenuSize;    {there are menu commands to step the FontSize}
  197.     fAllowedStyles := [bold, italic, underline];
  198.     
  199.     IF fStyleType = kWithStyle THEN
  200.         BEGIN
  201.         theStyleHandle := GetStylHandle(fHTE);
  202.         FailNil(theStyleHandle);
  203.         theStyleHandle^^.teRefCon := ORD(SELF);
  204.         END;
  205. {$ENDC}
  206.  
  207.     END;
  208. {--------------------------------------------------------------------------------------------------}
  209. {$S TEOpen}
  210.  
  211. PROCEDURE TFullTEView.IRes(itsDocument: TDocument; itsSuperView: TView; VAR itsParams: Ptr); OVERRIDE;
  212.  
  213.     VAR        theStyleHandle:        TEStyleHandle;
  214.  
  215.     BEGIN
  216.     
  217. {$IFC SubSuper}
  218.     fFullTypingCommand := NIL;
  219.     fAllowSubSuper := FALSE;    {cannot use Subscript/Superscript menu commands}
  220.     fSubSuperHandle := NIL;
  221. {$ENDC}
  222.  
  223.     INHERITED IRes(itsDocument, itsSuperView, itsParams);
  224.     InstallSlant(fHTE);
  225.     fSelAnchor := fHTE^^.selStart;
  226.     fUpDown := FALSE;
  227.     
  228. {$IFC MenuAccess}
  229.     fMenuFont := TRUE;            {can use Font menu commands}
  230.     fMenuSize := TRUE;            {can use Size menu commands}
  231.     fMenuStyle := TRUE;            {can use Style menu commands}
  232.     fMenuJust := FALSE;            {cannot use Justification menu commands}
  233.     fMenuUpDown := fMenuSize;    {there are menu commands to step the FontSize}
  234.     fAllowedStyles := [bold, italic, underline];
  235.     
  236.     IF fStyleType = kWithStyle THEN
  237.         BEGIN
  238.         theStyleHandle := GetStylHandle(fHTE);
  239.         FailNil(theStyleHandle);
  240.         theStyleHandle^^.teRefCon := ORD(SELF);
  241.         END;
  242. {$ENDC}
  243.  
  244.     END;
  245.     
  246. {--------------------------------------------------------------------------------------------------}
  247. {$S FullTERes}
  248.     
  249. FUNCTION TFullTEView.WordBounds(charPos: Integer; VAR wordStart, wordEnd: Integer): BOOLEAN;
  250.  
  251. { charPos is the offset of a specific character in the text            }
  252. { Returns:    TRUE iff that character is part of a word                }
  253. {            wordStart = offset of first character of the word        }
  254. {            wordEnd   = offset of final character of the word        }
  255. { Note: these are CHARACTER offsets, not CURSOR POSITIONS.            }
  256.  
  257.     VAR
  258.         wordChars, alphaNum:    SET of CHAR;
  259.         chLeft, chRight:        CHAR;
  260.         offs:                    OffSetTable;
  261.         i:                        INTEGER;
  262.         
  263.         
  264.     FUNCTION GetChar(charPos: Integer): CHAR;
  265.     BEGIN
  266.     GetChar := CHAR(Ptr(Ord4(fText^) + charPos)^);
  267.     END;
  268.     
  269.     
  270.     FUNCTION ValidBreak(iPos: Integer): BOOLEAN;
  271.  
  272. { Returns TRUE iff the CURSOR POSITION iPos does not fall within a word. }
  273.  
  274.     BEGIN
  275.     ValidBreak := TRUE;    
  276.     if (iPos > 0) & (iPos < fHTE^^.teLength) then
  277.         BEGIN
  278.         chLeft := GetChar(iPos-1);
  279.         chRight := GetChar(iPos);
  280.         if (chLeft IN wordChars) & (chRight IN wordChars) then
  281.             ValidBreak := FALSE
  282.         else if (chLeft = '.') | (chLeft = ',') then
  283.             BEGIN
  284.             if chRight IN ['0'..'9'] then
  285.                 if chLeft = '.' then
  286.                     ValidBreak := FALSE
  287.                 else if (iPos > 1) & (GetChar(iPos-2) IN ['0'..'9']) then
  288.                     ValidBreak := FALSE;
  289.             END
  290.         else if (chLeft = '''') & (chRight IN alphaNum) & (iPos > 1)
  291.                     & (GetChar(iPos-2) IN alphaNum) then
  292.             ValidBreak := FALSE
  293.         else if (chRight = '.') | ((chRight = ',') & (chLeft IN ['0'..'9'])) then
  294.             BEGIN
  295.             if (iPos < fHTE^^.teLength-1) & (GetChar(iPos+1) IN ['0'..'9']) then
  296.                 ValidBreak := FALSE;
  297.             END
  298.         else if (chRight = '''') & (chLeft IN alphaNum) & (iPos < fHTE^^.teLength-1)
  299.                     & (GetChar(iPos+1) IN alphaNum) then
  300.             ValidBreak := FALSE;
  301.         END;
  302.     END;
  303.     
  304.  
  305.     BEGIN
  306.     
  307.     wordStart := charPos;
  308.     wordEnd := charPos;
  309.         
  310.     if (charPos < 0) | (charPos > fHTE^^.teLength-1) then
  311.         BEGIN
  312.         WordBounds := FALSE;
  313.         EXIT(WordBounds);
  314.         END;
  315.     
  316.     if gNoScripts then
  317.     
  318.         BEGIN        {Based on Apple Human Interface Guidelines…}
  319.         alphaNum := ['A'..'Z','a'..'z','Ä'..'ü','ß'..'™','Æ','Ø','µ'..'ø',' '..'œ','ÿ','0'..'9'];
  320.         wordChars := alphaNum + ['$','¢','£','¥','%','-'];
  321.         
  322.         chLeft := GetChar(charPos);
  323.         
  324.         if chLeft IN wordChars then
  325.             WordBounds := TRUE
  326.         else if (chLeft = '.') | (chLeft = ',') | (chLeft = '''') then
  327.             WordBounds := NOT ValidBreak(charPos+1);
  328.     
  329.         while NOT ValidBreak(wordStart) do wordStart := wordStart - 1;
  330.         while NOT ValidBreak(wordEnd+1) do wordEnd := wordEnd + 1;
  331.         
  332.         END
  333.  
  334.     else    { if a non-Roman script is present, use the Script Manager routines }
  335.  
  336.         BEGIN        
  337.         REPEAT
  338.             i := CharByte(fText^, charPos);
  339.             charPos := charPos + 1;
  340.         UNTIL (i = 0) | (i = 1);
  341.         charPos := charPos -1;
  342.  
  343.         FindWord(fText^, fHTE^^.teLength, charPos, TRUE, NIL, offs);
  344.         wordStart := MIN(offs[0].offFirst, offs[0].offSecond - 1);
  345.         wordEnd := MAX(offs[0].offFirst, offs[0].offSecond - 1);
  346.         WordBounds := (wordStart < wordEnd) | (CharType(fText^, wordStart) MOD 8 <> smCharPunct);
  347.         
  348.         END
  349.     END;
  350.  
  351. {--------------------------------------------------------------------------------------------------}
  352. {$S FullTERes}
  353.  
  354. FUNCTION TFullTEView.TripleBounds(charPos: Integer;
  355.                                 VAR tripleStart, tripleEnd: Integer): BOOLEAN;
  356.  
  357. { Override this method if you want triple-click to select a sentence,    }
  358. { a line, the entire field, whatever.                                    }
  359.  
  360. { charPos is the offset of a specific character in the text                }
  361. { Returns:    TRUE iff that character is part of a "sentence"                }
  362. {            tripleStart = offset of first character of the "sentence"    }
  363. {            tripleEnd   = offset of final character of the "sentence"    }
  364. { Note: these are CHARACTER offsets, not CURSOR POSITIONS.                }
  365.  
  366.     BEGIN
  367.     TripleBounds := WordBounds(charPos, tripleStart, tripleEnd);
  368.     END;
  369.  
  370. {--------------------------------------------------------------------------------------------------}
  371. {$S FullTERes}
  372.  
  373. FUNCTION TFullTEView.DoCommandKey(ch: CHAR; VAR info: EventInfo): TCommand; OVERRIDE;
  374.  
  375. { unlike 2.0ß9 version of this method, we don't have to worry about "+" really
  376.  being Shift-"=", etc. For further important details, see
  377.  TApplication.DoCommandKey. }
  378.  
  379.     VAR        c:        cmdNumber;
  380.  
  381.     BEGIN
  382.     IF (ch >= chLeft) & (ch <= chDown) THEN
  383.         DoCommandKey := DoKeyCommand(ch, 0, info)
  384.     ELSE
  385.         BEGIN
  386.         DoCommandKey := gNoChanges;
  387.         fUpDown := FALSE;    
  388.         
  389.     {$IFC MenuAccess}
  390.         IF ch IN ['<','>'] THEN
  391.         
  392.             IF fMenuSize THEN        { this works even if NOT fMenuUpDown }
  393.                 IF ch = '<' THEN
  394.                     DoCommandKey := DoMenuCommand(cSizeNextDown)
  395.                 ELSE
  396.                     DoCommandKey := DoMenuCommand(cSizeNextUp)
  397.             ELSE
  398.                 gApplication.Beep(1)
  399.         ELSE
  400.     {$ENDC}
  401.     
  402.         DoCommandKey := INHERITED DoCommandKey(ch,info);
  403.         END
  404.     END;
  405.     
  406. {--------------------------------------------------------------------------------------------------}
  407. {$S FullTERes}
  408.  
  409. FUNCTION TFullTEView.DoKeyCommand(ch: Char; aKeyCode: INTEGER; VAR info: EventInfo): TCommand; OVERRIDE;
  410.  
  411.     VAR
  412.             handledCharacter, selecting:        Boolean;
  413.             goToPos, i, oldLine, nonAnchor:        Integer;
  414.             expanding:                            Boolean;
  415.             newStart, newEnd:                    Integer;
  416.             towardStart:                        Boolean;
  417.             aVPoint:                            VPoint;
  418.             
  419.     FUNCTION FindLine(selPos: Integer): Integer;
  420.         VAR
  421.             i:    Integer;
  422.         BEGIN
  423.         with fHTE^^ do
  424.             BEGIN
  425.             if nLines <= 1 then
  426.                 FindLine := 0
  427.             else
  428.                 BEGIN
  429.                 i := nLines-1;
  430.                 while lineStarts[i] > selPos do i := i - 1;
  431.                 FindLine := i;
  432.                 END;
  433.             END;
  434.         END;
  435.         
  436.     FUNCTION FindLineStart: Integer;
  437.         BEGIN
  438.         with fHTE^^ do
  439.             if nLines <= 1 then
  440.                 FindLineStart := 0
  441.             else
  442.                 FindLineStart := lineStarts[ FindLine(nonAnchor) ];
  443.         END;
  444.  
  445.     FUNCTION FindLineEnd: Integer;
  446.         VAR
  447.             i:    Integer;
  448.         BEGIN
  449.         with fHTE^^ do
  450.             BEGIN
  451.             if nLines <= 1 then
  452.                 FindLineEnd := teLength
  453.             else
  454.                 BEGIN
  455.                 i := nLines-1;
  456.                 while lineStarts[i] > nonAnchor do i := i - 1;
  457.                 if i < nLines-1 then
  458.                     FindLineEnd := lineStarts[i+1] - 1
  459.                 else
  460.                     FindLineEnd := teLength;
  461.                 END;
  462.             END;
  463.         END;
  464.  
  465.  
  466.     BEGIN
  467.     DoKeyCommand := gNoChanges;
  468.     handledCharacter := FALSE;
  469.     goToPos := fHTE^^.selStart;
  470.     selecting := FALSE;
  471.     
  472.     if (ch <> chUp) & (ch <> chDown) then fUpDown := FALSE;
  473.     
  474.     if (ch = chLeft) | (ch=chRight) then
  475.         BEGIN
  476.         towardStart := (ch = chLeft);
  477.         if NOT gNoScripts then
  478.             if GetScript(GetEnvirons(smKeyScript), smScriptRight) <> 0 then
  479.                 towardStart := NOT towardStart;
  480.         END
  481.     else
  482.         towardStart := FALSE;
  483.  
  484.     with fHTE^^ do
  485.         BEGIN
  486.         if selStart = selEnd then fSelAnchor := selStart;
  487.         if fSelAnchor < 0 then
  488.             if (ch = chUp) | (towardStart) then
  489.                 fSelAnchor := selEnd
  490.             else
  491.                 fSelAnchor := selStart;
  492.         if fSelAnchor = selEnd then nonAnchor := selStart
  493.         else nonAnchor := selEnd;
  494.         END;
  495.  
  496.     if (ch = chUp) & (FindLine(nonAnchor) = 0) then
  497.         BEGIN                                            {same as Cmd-Up}
  498.         selecting := info.theShiftKey;
  499.         handledCharacter := TRUE;
  500.         goToPos := 0;
  501.         fUpDown := FALSE;
  502.         END
  503.     else if (ch = chDown) & (FindLine(nonAnchor) = fHTE^^.nLines - 1) then
  504.         BEGIN                                            {same as Cmd-Down}
  505.         selecting := info.theShiftKey;
  506.         handledCharacter := TRUE;
  507.         goToPos := fHTE^^.teLength;
  508.         fUpDown := FALSE;
  509.         END;
  510.     
  511.     if (NOT handledCharacter) & (ch >= chLeft) & (ch <= chDown) then
  512.  
  513.         with fHTE^^ do
  514.         BEGIN
  515.         
  516.         HLock(handle(fHTE));
  517.  
  518.         selecting := info.theShiftKey;
  519.         handledCharacter := TRUE;
  520.  
  521.         if info.theCmdKey then                    { Actually, Cmd-Up & Cmd-Down differ from    }
  522.             BEGIN                                { the Human Interface Guidelines. Let me    }
  523.             if ch = chUp  then goToPos := 0        { know if you think this should be modified!}
  524.             else if ch = chDown then goToPos := teLength
  525.             else if towardStart then goToPos := FindLineStart
  526.             else goToPos := FindLineEnd;
  527.             fUpDown := FALSE;
  528.             END
  529.             
  530.         else if (ch = chUp) | (ch = chDown) then
  531.             BEGIN
  532.             if NOT fUpDown then
  533.                 BEGIN
  534.                 fUpDown := TRUE;
  535.                 i := OffsetToPt(nonAnchor).h;    { OffsetToPt might move memory, so }
  536.                 fUpDownH := i;                    { we'll be paranoid (by using "i") }
  537.                 END;
  538.             if lineHeight < 0 then    {styled text}
  539.                 BEGIN
  540.                 i := FindLine(nonAnchor);
  541.                 i := TEGetHeight(LONGINT(i), LONGINT(i), fHTE);
  542.                 END
  543.             else
  544.                 i := lineHeight;
  545.             if ch = chUp then i := -i;
  546.             aVPoint.v := OffsetToPt(nonAnchor).v + i;
  547.             aVPoint.h := fUpDownH;
  548.             goToPos := PtToOffset(aVPoint);
  549.             i := FindLine(nonAnchor);
  550.             if (ch = chUp) & (goToPos = lineStarts[i]) then
  551.                 goToPos := goToPos - 1
  552.             else if (ch = chDown) & (FindLine(goToPos) = i+2) then
  553.                 goToPos := goToPos + 1;
  554.             END
  555.  
  556.         else if info.theOptionKey {& ((ch = chLeft) | (ch = chRight))} then
  557.             BEGIN
  558.             if selecting then
  559.                 if towardStart then expanding := (nonAnchor <= fSelAnchor)
  560.                 else expanding := (nonAnchor >= fSelAnchor)
  561.             else
  562.                 expanding := TRUE;
  563.             goToPos := nonAnchor;
  564.             if NOT expanding then
  565.                 if towardStart then
  566.                     BEGIN
  567.                     newEnd := goToPos;
  568.                     while (goToPos > fSelAnchor) & ( (NOT WordBounds(goToPos, newStart, newEnd))
  569.                         | (newEnd+1 >= nonAnchor) ) do goToPos := newStart - 1;
  570.                     if goToPos <= fSelAnchor then
  571.                         BEGIN
  572.                         expanding := TRUE;
  573.                         goToPos := fSelAnchor;
  574.                         END
  575.                     else goToPos := newEnd + 1;
  576.                     END
  577.                 else {NOT towardStart}
  578.                     BEGIN
  579.                     newStart := goToPos;
  580.                     while (goToPos < fSelAnchor) & ( (NOT WordBounds(goToPos, newStart, newEnd))
  581.                         | (newStart <= nonAnchor) ) do goToPos := newEnd + 1;
  582.                     if goToPos >= fSelAnchor then
  583.                         BEGIN
  584.                         expanding := TRUE;
  585.                         goToPos := fSelAnchor;
  586.                         END;
  587.                     END;            
  588.             if expanding then
  589.                 if towardStart then
  590.                     BEGIN
  591.                     i := goToPos;
  592.                     newStart := goToPos;
  593.                     while (goToPos > 0) & ( (NOT WordBounds(goToPos, newStart, newEnd))
  594.                         | (newStart >= i) ) do goToPos := goToPos - 1;
  595.                     goToPos := MIN(goToPos,newStart)
  596.                     END
  597.                 else {NOT towardStart}
  598.                     BEGIN
  599.                     newEnd := goToPos;
  600.                     i := fHTE^^.teLength - 1;
  601.                     while (goToPos < i) & NOT WordBounds(goToPos+1, newStart, newEnd)
  602.                         do goToPos := goToPos + 1;
  603.                     goToPos := MAX(goToPos,newEnd) + 1;
  604.                     END;
  605.             END
  606.  
  607.         else if info.theShiftKey | (selStart = selEnd) {& ((ch = chLeft) | (ch = chRight))} then
  608.             BEGIN
  609.             if towardStart then
  610.                 i := -1
  611.             else
  612.                 i := +1;
  613.             goToPos := MIN(MAX(nonAnchor + i, 0), teLength);
  614.             END
  615.  
  616.         else {selStart <> selEnd & ((ch = chLeft) | (ch = chRight))}
  617.             BEGIN
  618.             if towardStart then
  619.                 goToPos := selStart
  620.             else
  621.                 goToPos := selEnd;
  622.             END;
  623.                 
  624.         HUnlock(handle(fHTE));
  625.         
  626.         END;
  627.         
  628.     if handledCharacter then
  629.         BEGIN
  630.         DoneTyping;
  631.         if selecting then
  632.             SetSelection(MIN(goToPos,fSelAnchor), MAX(goToPos,fSelAnchor), kRedraw)
  633.         else
  634.             SetSelection(goToPos, goToPos, kRedraw);
  635.         END
  636.     else
  637.         BEGIN
  638. {$IFC SubSuper}
  639.         DoKeyCommand := OldDoKeyCommand(ch, aKeyCode, info);
  640. {$ELSEC}
  641.         DoKeyCommand := INHERITED DoKeyCommand(ch, aKeyCode, info);
  642. {$ENDC}        
  643.         with fHTE^^ do
  644.             if selecting then
  645.                 SetSelection(MIN(selStart,fSelAnchor), MAX(selEnd,fSelAnchor), kRedraw)
  646.             else
  647.                 if selStart = selEnd then fSelAnchor := selStart;
  648.         END;
  649.     END;
  650.     
  651. {--------------------------------------------------------------------------------------------------}
  652. {$S FullTERes}
  653. {$PUSH}{$IFC qTRACE}{$D+}{$ENDC}
  654.  
  655. PROCEDURE DoHigh(theTEPtr: TEPtr; pos1, pos2: INTEGER); EXTERNAL;
  656.  
  657.  
  658. PROCEDURE TFullTEView.DrawSelection(newStart, newEnd: INTEGER);
  659.     
  660.     VAR            theRect:        Rect;
  661.  
  662.     BEGIN
  663.     WITH fHTE^^ DO
  664.         IF (newStart <> selStart) | (newEnd <> selEnd) THEN
  665.             IF (newStart >= newEnd) | (selStart >= selEnd) THEN
  666.                 TESetSelect(newStart, newEnd, fHTE)
  667.             ELSE
  668.             {    TESetSelect(newStart, newEnd, fHTE);  <-- This flashes too much! }
  669.                 BEGIN
  670.                 
  671.                 GetQDExtent(theRect);
  672.                 theRect.left := theRect.left + fInset.left;
  673.                 theRect.right := theRect.right - fInset.right;
  674.                 ClipFurtherTo(theRect, 0, 0);        { <-- avoid highlighting the insets }
  675.                 
  676.                 HLock(Handle(fHTE));
  677.                 IF newStart <> selStart THEN
  678.                     DoHigh(fHTE^, MIN(newStart, selStart), MAX(newStart, selStart));
  679.                 IF newEnd <> selEnd THEN
  680.                     DoHigh(fHTE^, MIN(newEnd, selEnd), MAX(newEnd, selEnd));
  681.                 HUnlock(Handle(fHTE));
  682.                 
  683.                 selStart := newStart;
  684.                 selEnd := newEnd;
  685.                 END;
  686.     END;
  687. {$POP}
  688.  
  689. {--------------------------------------------------------------------------------------------------}
  690. {$S FullTERes}
  691.  
  692. PROCEDURE TFullTEView.SetSelection(NewSelStart, NewSelEnd: INTEGER; redraw: BOOLEAN);
  693.  
  694.     BEGIN
  695.     with fHTE^^ do
  696.         BEGIN
  697.         IF redraw & Focus THEN
  698.             BEGIN
  699.             DrawSelection(MAX(NewSelStart, 0), MIN(NewSelEnd, fHTE^^.teLength));
  700.             SynchView(TRUE);
  701.             END
  702.         ELSE
  703.             SetSelect(MAX(NewSelStart, 0), MIN(NewSelEnd, fHTE^^.teLength), fHTE);
  704.  
  705.         if NewSelStart = NewSelEnd then fSelAnchor := NewSelStart;
  706.  
  707.         END;
  708.     fSpecsChanged := TRUE;
  709. {$IFC SubSuper}
  710.     if fAllowSubSuper then
  711.         WITH fSubSuperHandle^^ DO
  712.             BEGIN
  713.             nullSubSuper := undefined;
  714.             nullBaseSize := 0;
  715.             END;
  716. {$ENDC}
  717.     END;
  718. {--------------------------------------------------------------------------------------------------}
  719. {$S FullTERes}
  720.  
  721. FUNCTION TFullTEView.DoMouseCommand(VAR theMouse: Point; VAR info: EventInfo;
  722.                                 VAR hysteresis: Point): TCommand; OVERRIDE;
  723.     VAR
  724.             aTEMouseCommand:    TFullTEMouseCommand;
  725.             aRect, bRect:        Rect;
  726.             i, j:                Integer;
  727.             itsDown:            Boolean;
  728.  
  729.     BEGIN
  730.     
  731.     IF Focus & IsVisible THEN
  732.         BEGIN
  733.         pCurrTEView := SELF;
  734.         DoneTyping;                                     { Mousedown terminates the Typing command }
  735.         fSpecsChanged := TRUE;
  736.     {    pAutoScrolled := FALSE;                         { Will get set to true by AutoScrollTEView }
  737.         fUpDown := FALSE;
  738.         
  739.         NEW(aTEMouseCommand);
  740.         FailNil(aTEMouseCommand);
  741.         aTEMouseCommand.ITEMouseCommand(SELF, info.theShiftKey);
  742.         DoMouseCommand := aTEMouseCommand;
  743.         
  744.     {    IF pAutoScrolled THEN                            { If we autoscrolled… }
  745.     {        BEGIN
  746.     {        gApplication.InvalidateFocus;                { …force a re-focus }
  747.     {        IF Focus THEN;
  748.     {        END;
  749.     }    END;
  750.         
  751.     END;
  752.     
  753. {--------------------------------------------------------------------------------------------------}
  754. {$S TESelCommand}
  755.  
  756. FUNCTION TFullTEView.DoMakeEditCommand(aCmdNumber: CmdNumber): TTECommand; OVERRIDE;
  757.  
  758.     VAR
  759.         aCutCopyCommand:    TFullTECutCopyCommand;    {The only difference      }
  760.         aPasteCommand:        TFullTEPasteCommand;    { is in using the "Full" }
  761.         aClearCommand:        TFullTECommand;            { TTECommand classes.     }
  762.  
  763.     BEGIN
  764.     CASE aCmdNumber OF
  765.         cCut, cCopy:
  766.             BEGIN
  767.             New(aCutCopyCommand);
  768.             FailNIL(aCutCopyCommand);
  769.             aCutCopyCommand.ITECutCopyCommand(SELF, aCmdNumber);
  770.             DoMakeEditCommand := aCutCopyCommand;
  771.             END;
  772.  
  773.         cPaste:
  774.             BEGIN
  775.             New(aPasteCommand);
  776.             FailNIL(aPasteCommand);
  777.             aPasteCommand.ITEPasteCommand(SELF);
  778.             DoMakeEditCommand := aPasteCommand;
  779.             END;
  780.  
  781.         cClear:
  782.             BEGIN
  783.             New(aClearCommand);
  784.             FailNIL(aClearCommand);
  785.             aClearCommand.ITECommand(SELF, aCmdNumber, TRUE);
  786.             DoMakeEditCommand := aClearCommand;
  787.             END;
  788.  
  789.     END;
  790.     END;
  791.  
  792. {--------------------------------------------------------------------------------------------------}
  793. {$S FullTERes}
  794.  
  795. FUNCTION TFullTEView.PtToOffset(point: VPoint): INTEGER;
  796.  
  797.     { Note: the following converts view coordinates to cursor position.        }
  798.     { If Script Manager is present, then so must be Styled TextEdit, and    }
  799.     { as the Script Manager should have patched TEGetOffset, we don't have    }
  800.     { to deal explicitly with scripts here.                                    }
  801.     
  802.     { Note #2: if there's no Styled TextEdit, and if the field is not left-    }
  803.     { justified, the following code will screw up. Let me know if you care    }
  804.     { about such things.                                                    }
  805.  
  806.     VAR
  807.             pos, lineNo, lineStart:            INTEGER;
  808.             nextLine, height, horiz:        INTEGER;
  809.             aRect:                            Rect;
  810.             theQDPt:                        Point;
  811.  
  812.     BEGIN
  813.     IF Focus THEN                        { Formerly we assumed focused, but    }
  814.                                         { I've since encountered situations }
  815.         BEGIN                            { where that may not be true.        }
  816.  
  817.     {$IFC NOT qNeedsStyleTextEdit}
  818.         IF gConfiguration.hasStyleTextEdit THEN
  819.     {$ENDC}
  820.             BEGIN
  821.             theQDPt := ViewToQDPt(point);
  822.             IF theQDPt.v < 0 THEN   { TEGetOffset returns the wrong value on a }
  823.                 PtToOffset := 0         {  IIfx if the v coordinate is negative.   }
  824.             ELSE
  825.                 PtToOffset := TEGetOffset(theQDPt, fHTE)
  826.             END
  827.     {$IFC NOT qNeedsStyleTextEdit}
  828.         ELSE
  829.             BEGIN
  830.             GetQDExtent(aRect);
  831.             height := aRect.bottom - fInset.bottom;
  832.             horiz := ViewToQDPt(point).h - fInset.left;
  833.             HLock(Handle(fHTE));
  834.             WITH fHTE^^ DO
  835.                 BEGIN
  836.                 TextFont(txFont);        { <-- I wouldn't have thought }
  837.                 TextFace(txFace);        { <-- that we'd need these,   }
  838.                 TextSize(txSize);        { <-- but it turns out we do! }
  839.                 HLock(Handle(hText));            {<- necessary???}
  840.                 lineNo := 
  841.                     MIN( MAX(ViewToQDPt(point).v - fInset.top, 0), height)
  842.                     DIV lineHeight;
  843.                 lineStart := lineStarts[lineNo];
  844.                 if lineNo = nLines - 1 then
  845.                     nextLine := teLength + 1
  846.                 else
  847.                     nextLine := lineStarts[lineNo + 1];
  848.                 pos := lineStart + 1;
  849.                 WHILE (pos < nextLine)
  850.                     & (TextWidth(hText^, lineStart, pos-lineStart)
  851.                         - (CharWidth(CHAR(PTR(ORD4(hText^) + pos - 1)^)) DIV 2)
  852.                         <= horiz) DO
  853.                     BEGIN
  854.                     pos := pos + 1;
  855.                     END;
  856.                 PtToOffset := pos - 1;
  857.                 HUnlock(Handle(hText));
  858.                 END;
  859.             HUnlock(Handle(fHTE));
  860.             END
  861.     {$ENDC};
  862.         END
  863.     else
  864.         PtToOffset := 0;        { ...as good a value to return as any }
  865.     END;
  866.  
  867. {--------------------------------------------------------------------------------------------------}
  868. {$S FullTERes}
  869.  
  870. FUNCTION TFullTEView.OffsetToPt(offset: Integer): VPoint;
  871.  
  872.     { Note: the following converts cursor position to view coordinates.        }
  873.     { If Script Manager is present, then so must be Styled TextEdit, and    }
  874.     { as the Script Manager should have patched TEGetOffset, we don't have    }
  875.     { to deal explicitly with scripts here.                                    }
  876.     
  877.     { Note #2: if there's no Styled TextEdit, and if the field is not left-    }
  878.     { justified, the following code will screw up. Let me know if you care    }
  879.     { about such things.                                                    }
  880.     
  881.     VAR
  882.             lineNo, lineStart, height:    INTEGER;
  883.             thePoint:                    Point;
  884.             theStyle:                    TextStyle;
  885.             ascent:                        INTEGER;
  886.  
  887.     BEGIN
  888.     if Focus then                        { Formerly we assumed focused, but    }
  889.                                         { I've since encountered situations }
  890.         BEGIN                            { where that may not be true.        }
  891.  
  892.     {$IFC NOT qNeedsStyleTextEdit}
  893.         if gConfiguration.hasStyleTextEdit then
  894.     {$ENDC}
  895.             BEGIN
  896.             TEGetStyle(offset, theStyle, height, ascent, fHTE);
  897.             if fHTE^^.teLength <= 0 then    {Work-around for TEGetPoint bug (through System 6.0.4:}
  898.                 SetPt(thePoint,  fInset.left, fInset.top)
  899.             else
  900.                 thePoint := TEGetPoint(offset, fHTE);
  901.             thePoint.v := thePoint.v - height + ascent;
  902.             END
  903.             
  904.     {$IFC NOT qNeedsStyleTextEdit}
  905.         else
  906.             BEGIN
  907.             HLock(Handle(fHTE));
  908.             WITH fHTE^^ DO
  909.                 BEGIN
  910.                 TextFont(txFont);        { <-- I wouldn't have thought }
  911.                 TextFace(txFace);        { <-- that we'd need these,   }
  912.                 TextSize(txSize);        { <-- but it turns out we do! }
  913.                 HLock(Handle(hText));            {<- necessary???}
  914.                 lineNo := 0;
  915.                 while (lineNo < nLines - 1) & (lineStarts[lineNo + 1] <= offset) DO
  916.                     lineNo := lineNo + 1;
  917.                 lineStart := lineStarts[lineNo];
  918.  
  919.                 thePoint.v := fInset.top + (lineNo * lineHeight) + fontAscent;
  920.                 thePoint.h := fInset.left + TextWidth(hText^, lineStart, offset-lineStart);
  921.                 
  922.                 HUnlock(Handle(hText));
  923.                 END;
  924.             HUnlock(Handle(fHTE));
  925.             END
  926.     {$ENDC};
  927.     
  928.         QDToViewPt(thePoint, OffsetToPt);
  929.         END
  930.     else
  931.         OffsetToPt := gZeroVpt;        { ...as good a value to return as any }        
  932.  
  933.     END;
  934.  
  935. {--------------------------------------------------------------------------------------------------}
  936. {--------------------------------------------------------------------------------------------------}
  937. {$IFC MenuAccess}
  938. {--------------------------------------------------------------------------------------------------}
  939. {$IFC SubSuper}
  940.  
  941. {$S FullTERes}
  942.  
  943. FUNCTION GetIndex(theSubSuper: SubSuperHandle; charPos: INTEGER): INTEGER;
  944.  
  945.     VAR        i:            INTEGER;
  946.     
  947.     BEGIN
  948.     WITH theSubSuper^^ DO
  949.         BEGIN
  950.         charPos := MIN(MAX(charPos, 0), runs[nRuns].startChar - 1);
  951.         i := 0;
  952.         WHILE runs[i].startChar < charPos DO
  953.             i := i + 1;
  954.         if runs[i].startChar > charPos then
  955.             i := i - 1;
  956.         GetIndex := i;
  957.         END;
  958.     END;
  959.     
  960. {$ENDC}
  961. {--------------------------------------------------------------------------------------------------}
  962. {$S FullTERes}
  963.  
  964. PROCEDURE TFullTEView.DoSetupMenus; OVERRIDE;
  965.  
  966.     VAR
  967.         hasStyle:            BOOLEAN;
  968.         checkPlain:         BOOLEAN;
  969.         checkSize:            BOOLEAN;
  970.         checkFont:            BOOLEAN;
  971.         continStyle:        BOOLEAN;
  972.         aBoolean:             BOOLEAN;
  973.         just:                INTEGER;
  974.         item:                INTEGER;
  975.         fnt:                INTEGER;
  976.         c:                    INTEGER;
  977.         aMode:                INTEGER;
  978.         aFace:                Style;
  979.         aMenuHandle:        MenuHandle;
  980.         aName:                Str255;
  981.         aStyle:             TextStyle;
  982.         theFont:            INTEGER;
  983.         theSize:            INTEGER;
  984.         startOfSelection:    INTEGER;
  985.         endOfSelection:     INTEGER;
  986.         aStr255:            Str255;
  987.     {$IFC SubSuper}
  988.         bMode:                INTEGER;
  989.         bStyle:                TextStyle;
  990.         theSubSuper:        SubOrSuper;
  991.         theBaseSize:        INTEGER;
  992.         continSubSuper:        BOOLEAN;
  993.         index:                INTEGER;
  994.         loopFlag:            BOOLEAN;
  995.     {$ENDC}
  996.  
  997.     BEGIN
  998.     INHERITED DoSetupMenus;
  999.  
  1000.     hasStyle := gConfiguration.hasStyleTextEdit;
  1001.  
  1002.     {$IFC NOT qNeedsStyleTextEdit}
  1003.     IF NOT hasStyle THEN
  1004.         BEGIN
  1005.         aStyle := fTextStyle;
  1006.         checkPlain := aStyle.tsFace = [];
  1007.         checkFont := TRUE;
  1008.         continStyle := TRUE;
  1009.         END
  1010.     ELSE
  1011.     {$ENDC}
  1012.         BEGIN
  1013.         WITH fHTE^^ DO
  1014.             BEGIN
  1015.             startOfSelection := selStart;
  1016.             endOfSelection := selEnd;
  1017.             END;
  1018.         aMode := doFace;
  1019.         {$IFC SubSuper}
  1020.         if fAllowSubSuper then
  1021.             continSubSuper := ContinuousSubSuper(startOfSelection, endOfSelection, theSubSuper, theBaseSize)
  1022.         else
  1023.             BEGIN
  1024.             continSubSuper := TRUE;
  1025.             theSubSuper := normal;
  1026.             END;
  1027.         {$ENDC}
  1028.         checkPlain := ContinuousStyle(startOfSelection, endOfSelection, aMode, aStyle)
  1029.                       & (aStyle.tsFace = [])
  1030.                 {$IFC SubSuper}
  1031.                       & continSubSuper & (theSubSuper = normal)
  1032.                 {$ENDC};
  1033.         aMode := doAll;
  1034.         aStyle.tsFace := [bold, italic, underline, outline, shadow, extend, condense];
  1035.         aBoolean := ContinuousStyle(startOfSelection, endOfSelection, aMode, aStyle);
  1036.         checkFont := BAND(aMode, doFont) <> 0;
  1037.         continStyle := BAND(aMode, doFace) <> 0;
  1038.         
  1039.         {$IFC SubSuper}
  1040.         IF ( BAND(aMode, doSize) = 0 ) & ( NOT continSubSuper ) THEN
  1041.             BEGIN
  1042.             loopFlag := FALSE;
  1043.             FOR index := GetIndex(fSubSuperHandle, startOfSelection) TO GetIndex(fSubSuperHandle, endOfSelection - 1) DO
  1044.                 BEGIN
  1045.                 WITH fSubSuperHandle^^.runs[index] DO
  1046.                     IF subSuper = normal THEN
  1047.                         BEGIN
  1048.                         bMode := doSize;
  1049.                         aBoolean := ContinuousStyle(MAX(startChar, startOfSelection),
  1050.                                                     MIN(fSubSuperHandle^^.runs[index + 1].startChar, endOfSelection),
  1051.                                                     bMode, bStyle);
  1052.                         if BAND(bMode, doSize) <> 0 then
  1053.                             theBaseSize := bStyle.tsSize
  1054.                         else
  1055.                             theBaseSize := -1;
  1056.                         END
  1057.                     ELSE
  1058.                         theBaseSize := baseSize;
  1059.                 IF theBaseSize = 0 THEN theBaseSize := GetDefFontSize;
  1060.                 IF NOT loopFlag THEN
  1061.                     BEGIN
  1062.                     IF theBaseSize = -1 THEN Leave;
  1063.                     aStyle.tsSize := theBaseSize;
  1064.                     loopFlag := TRUE;
  1065.                     END
  1066.                 ELSE IF theBaseSize <> aStyle.tsSize THEN Leave;
  1067.                 END;
  1068.             IF ( theBaseSize = aStyle.tsSize ) & ( theBaseSize <> -1 ) THEN aMode := aMode + doSize;
  1069.             END;
  1070.         {$ENDC}
  1071.         
  1072.         END;
  1073.  
  1074.     if fMenuFont then
  1075.         BEGIN
  1076.         aMenuHandle := GetMHandle(mFont);
  1077.         GetFontName(aStyle.tsFont, aName);                    { Get real font number in case tsFont is }
  1078.         GetFNum(aName, theFont);                            { …the system or application font. }
  1079.         FOR item := 1 TO CountMItems(aMenuHandle) DO
  1080.             BEGIN
  1081.       { There can be more than 31 menu entries with scrolling menus, but trying to enable
  1082.        an item with number > 31 is bad news.  If the menu itself is enabled (which it
  1083.        will be in MacApp if any of the first 31 items is enabled), then the extras
  1084.        will always be enabled. }
  1085.             IF item <= 31 THEN
  1086.                 EnableItem(aMenuHandle, item);
  1087.             IF checkFont THEN
  1088.                 BEGIN
  1089.                 GetItem(aMenuHandle, item, aName);
  1090.                 GetFNum(aName, fnt);
  1091.                 CheckItem(aMenuHandle, item, fnt = theFont);
  1092.                 END;
  1093.             END;
  1094.         END;
  1095.  
  1096.     if fMenuJust then
  1097.         BEGIN
  1098.         just := fJustification;
  1099.         EnableCheck(cJustLeft, TRUE, (just = teForceLeft));
  1100.         EnableCheck(cJustCenter, TRUE, (just = teJustCenter));
  1101.         EnableCheck(cJustRight, TRUE, (just = teJustRight));
  1102.         END;
  1103.  
  1104.     {$IFC NOT qNeedsHierarchicalMenus}
  1105.     IF gConfiguration.hasHierarchicalMenus THEN
  1106.     {$ENDC}
  1107.         BEGIN
  1108.         if kSubStyle then Enable(cStyle, TRUE);
  1109.         if kSubSize then Enable(cSize, TRUE);
  1110.         if kSubFont then Enable(cFont, TRUE);
  1111.         END;
  1112.  
  1113.     if fMenuStyle then    
  1114.         BEGIN
  1115.         aFace := aStyle.tsFace;
  1116.         EnableCheck(cPlainText, TRUE, checkPlain);
  1117.         if bold IN fAllowedStyles then EnableCheck(cBold, TRUE, continStyle & (bold IN aFace));
  1118.         if italic IN fAllowedStyles then EnableCheck(cItalic, TRUE, continStyle & (italic IN aFace));
  1119.         if underline IN fAllowedStyles then EnableCheck(cUnderline, TRUE, continStyle & (underline IN aFace));
  1120.         if outline IN fAllowedStyles then EnableCheck(cOutline, TRUE, continStyle & (outline IN aFace));
  1121.         if shadow IN fAllowedStyles then EnableCheck(cShadow, TRUE, continStyle & (shadow IN aFace));
  1122.         if condense IN fAllowedStyles then EnableCheck(cCondense, TRUE, continStyle & (condense IN aFace));
  1123.         if extend IN fAllowedStyles then EnableCheck(cExtend, TRUE, continStyle & (extend IN aFace));
  1124.     {$IFC SubSuper}
  1125.         if fAllowSubSuper then
  1126.             BEGIN
  1127.             EnableCheck(cSubscript, TRUE, continSubSuper & (theSubSuper = subscript));
  1128.             EnableCheck(cSuperscript, TRUE, continSubSuper & (theSubSuper = superscript));
  1129.             END;
  1130.     {$ENDC}
  1131.         END;
  1132.  
  1133.     if fMenuSize then
  1134.         BEGIN
  1135.         {$IFC SubSuper}
  1136.         if continSubSuper & (theSubSuper <> normal) then
  1137.             theSize := theBaseSize
  1138.         else
  1139.         {$ENDC}
  1140.             theSize := aStyle.tsSize;
  1141.         if theSize = 0 then theSize := GetDefFontSize;
  1142.         FOR c := cSizeMin TO cSizeMax DO
  1143.             BEGIN
  1144.             IF hasStyle & (BAND(aMode, doSize) = 0) THEN
  1145.                 checkSize := FALSE
  1146.             ELSE
  1147.                 checkSize := (c - cSizeBase) = theSize;
  1148.             EnableCheck(c, TRUE, checkSize);
  1149.             IF RealFont(aStyle.tsFont,c - cSizeBase) THEN
  1150.                 aFace := [outline]
  1151.             ELSE
  1152.                 aFace := [];
  1153.             SetStyle(c, aFace);
  1154.             END;
  1155.         if fMenuUpDown then
  1156.             BEGIN
  1157.             Enable(cSizeNextUp, TRUE);
  1158.             Enable(cSizeNextDown, TRUE);
  1159.             END;
  1160.         END;
  1161.  
  1162.     fSpecsChanged := FALSE;
  1163.     END;
  1164.  
  1165. {--------------------------------------------------------------------------------------------------}
  1166. {$S FullTERes}
  1167.  
  1168. FUNCTION TFullTEView.DoMenuCommand(aCmdNumber: CmdNumber): TCommand; OVERRIDE;
  1169.  
  1170.     VAR
  1171.         aName:                Str255;
  1172.         menu:                INTEGER;
  1173.         item:                INTEGER;
  1174.         newStyle:            TextStyle;
  1175.         aStyleItem:         StyleItem;
  1176.  
  1177.  
  1178.     PROCEDURE DoSizeChange(base: CmdNumber);
  1179.  
  1180.         BEGIN
  1181.         newStyle.tsSize := aCmdNumber - base;
  1182. {$IFC SubSuper}
  1183.         IF fAllowSubSuper THEN
  1184.             DoMenuCommand := DoMakeFullStyleCommand(newStyle, cSizeChange, doSize)
  1185.         ELSE
  1186. {$ENDC}
  1187.             DoMenuCommand := DoMakeStyleCommand(newStyle, cSizeChange, doSize);
  1188.         END;
  1189.  
  1190.  
  1191.     PROCEDURE DoRelSizeChange(upDown: INTEGER);
  1192.     
  1193.         VAR        theSize, aMode, maximumFontSize:    INTEGER;
  1194.                 startOfSelection, endOfSelection:    INTEGER;
  1195.  
  1196.         BEGIN
  1197.         
  1198.         maximumFontSize := 127;    { <- will change for System 7.0 ! }
  1199.         
  1200.         WITH fHTE^^ DO
  1201.             BEGIN
  1202.             startOfSelection := selStart;
  1203.             endOfSelection := selEnd;
  1204.             END;
  1205.  
  1206.         aMode := doSize;
  1207.         if ContinuousStyle(startOfSelection, endOfSelection, aMode, newStyle) then
  1208.             BEGIN
  1209.             theSize := newStyle.tsSize;
  1210.             if theSize = 0 then theSize := GetDefFontSize;
  1211.             if upDown = kSizeNextUp then
  1212.                 if (theSize + cSizeBase < cSizeMax)
  1213.                  & ((theSize *3) DIV 2 + cSizeBase >= cSizeMin) then
  1214.                     BEGIN
  1215.                     FOR theSize := theSize + 1 TO cSizeMax - cSizeBase DO
  1216.                         if CmdEnabled(theSize + cSizeBase) then Leave;
  1217.                     END
  1218.                 else
  1219.                     theSize := (theSize * 3) DIV 2
  1220.             else if (theSize + cSizeBase > cSizeMin)
  1221.                    & ((theSize + theSize) DIV 3 + cSizeBase <= cSizeMax) then
  1222.                 BEGIN
  1223.                 FOR theSize := theSize - 1 DOWNTO cSizeMin - cSizeBase DO
  1224.                     if CmdEnabled(theSize + cSizeBase) then Leave;
  1225.                 END
  1226.             else
  1227.                 theSize := (theSize + theSize) DIV 3;
  1228.             if (theSize > 1) & (theSize < maximumFontSize) then
  1229.                 BEGIN
  1230.                 newStyle.tsSize := theSize;
  1231. {$IFC SubSuper}
  1232.                 IF fAllowSubSuper THEN
  1233.                     DoMenuCommand := DoMakeFullStyleCommand(newStyle, cSizeChange, doSize)
  1234.                 ELSE
  1235. {$ENDC}
  1236.                     DoMenuCommand := DoMakeStyleCommand(newStyle, cSizeChange, doSize);
  1237.                 END;
  1238.             END
  1239.         else
  1240.     { The following is a bit of a cop-out. It would be easy enough to loop     }
  1241.     { through the selection's continuous-size runs, applying the above code     }
  1242.     { to each in turn. However if that's all we did, then each run would be     }
  1243.     { resized by a separate StyleCommand, and only the final one would be     }
  1244.     { undoable. One *could* create a new class of command objects to do this }
  1245.     { correctly; let me know if you're volunteering.                         }
  1246.             BEGIN
  1247.             newStyle.tsSize := kRelSizeDelta * upDown;
  1248. {$IFC SubSuper}
  1249.             IF fAllowSubSuper THEN
  1250.                 DoMenuCommand := DoMakeFullStyleCommand(newStyle, cSizeChange, addSize)
  1251.             ELSE
  1252. {$ENDC}
  1253.                 DoMenuCommand := DoMakeStyleCommand(newStyle, cSizeChange, addSize);
  1254.             END;
  1255.             
  1256.         END;
  1257.  
  1258.  
  1259.     PROCEDURE DoFontChange;
  1260.  
  1261.         BEGIN
  1262.         GetItem(GetMHandle(menu), item, aName);
  1263.         GetFNum(aName, newStyle.tsFont);
  1264.         DoMenuCommand := DoMakeStyleCommand(newStyle, cFontChange, doFont + doToggle);
  1265.         END;
  1266.  
  1267.  
  1268.     PROCEDURE DoJustChange;
  1269.  
  1270.         VAR
  1271.             newJust:            INTEGER;
  1272.             aJustChange:        TJustCommand;
  1273.  
  1274.         BEGIN
  1275.         CASE aCmdNumber OF
  1276.             cJustLeft:
  1277.                 newJust := teForceLeft;
  1278.             cJustCenter:
  1279.                 newJust := teJustCenter;
  1280.             cJustRight:
  1281.                 newJust := teJustRight;
  1282.         END;
  1283.         New(aJustChange);
  1284.         FailNIL(aJustChange);
  1285.         aJustChange.IJustCommand(SELF, newJust);
  1286.         DoMenuCommand := aJustChange;
  1287.         END;
  1288.  
  1289.  
  1290.     PROCEDURE DoPlainChange;
  1291.  
  1292.         BEGIN
  1293. {$IFC SubSuper}
  1294.         IF fAllowSubSuper THEN
  1295.             DoMenuCommand := DoSubSuperCommand(aCmdNumber)
  1296.         ELSE
  1297. {$ENDC}
  1298.             BEGIN
  1299.             newStyle.tsFace := [];
  1300.             DoMenuCommand := DoMakeStyleCommand(newStyle, cStyleChange, doFace);
  1301.             END;
  1302.         END;
  1303.  
  1304.  
  1305.     PROCEDURE DoStyleChange;
  1306.  
  1307.         BEGIN
  1308.         WITH newStyle DO
  1309.             CASE aCmdNumber OF
  1310.                 cBold:
  1311.                     tsFace := [bold];
  1312.                 cItalic:
  1313.                     tsFace := [italic];
  1314.                 cUnderline:
  1315.                     tsFace := [underline];
  1316.                 cOutline:
  1317.                     tsFace := [outline];
  1318.                 cShadow:
  1319.                     tsFace := [shadow];
  1320.                 cCondense:
  1321.                     tsFace := [condense];
  1322.                 cExtend:
  1323.                     tsFace := [extend];
  1324.             END;
  1325.         DoMenuCommand := DoMakeStyleCommand(newStyle, cStyleChange, doFace + doToggle);
  1326.         END;
  1327.  
  1328.  
  1329.     PROCEDURE DoSubSuperChange;
  1330.     
  1331.         BEGIN
  1332.         DoMenuCommand := DoSubSuperCommand(aCmdNumber);
  1333.         END;
  1334.  
  1335.  
  1336.     BEGIN                                                { DoMenuCommand }
  1337.     CmdToMenuItem(aCmdNumber, menu, item);
  1338.  
  1339.     if ((menu = mFont) & fMenuFont) | ((menu = mSize) & fMenuSize) |
  1340.         ((menu = mStyle) & fMenuStyle) | ((menu = mJust) & fMenuJust) then
  1341.  
  1342.         BEGIN
  1343.         DoMenuCommand := gNoChanges;
  1344.  
  1345.         IF menu = mFont THEN
  1346.             DoFontChange
  1347.         ELSE
  1348.             CASE aCmdNumber OF
  1349.                 cSizeMin..cSizeMax:
  1350.                     DoSizeChange(cSizeBase);
  1351.     
  1352.                 cSizeNextUp:
  1353.                     DoRelSizeChange(kSizeNextUp);
  1354.     
  1355.                 cSizeNextDown:
  1356.                     DoRelSizeChange(kSizeNextDown);
  1357.     
  1358.                 cJustLeft..cJustRight:
  1359.                     DoJustChange;
  1360.     
  1361.                 cPlainText:
  1362.                     DoPlainChange;
  1363.     
  1364.                 cBold..cExtend:
  1365.                     DoStyleChange;
  1366.                     
  1367.         {$IFC SubSuper}
  1368.                 cSubscript..cSuperScript:
  1369.                     DoSubSuperChange;
  1370.         {$ENDC}
  1371.     
  1372.                 OTHERWISE
  1373.                     DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
  1374.             END;
  1375.         END
  1376.     else
  1377.         DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
  1378.     END;
  1379.  
  1380. {--------------------------------------------------------------------------------------------------}
  1381. {$S FullTERes}
  1382. FUNCTION TFullTEView.DoSetCursor(localPoint: Point; cursorRgn: RgnHandle): BOOLEAN; OVERRIDE;
  1383.  
  1384.     VAR
  1385.         myCursor:                        BOOLEAN;
  1386.         qdExtent:                        Rect;
  1387.         offset, lineHeight, fontAscent:    INTEGER;
  1388.         aStyle:                         TextStyle;
  1389.  
  1390.     BEGIN
  1391.     myCursor := FALSE;
  1392.     IF SELF <> gClipView THEN
  1393.         BEGIN
  1394.         IF localPoint.v < 0 THEN             { for IIfx bug in TEGetOffset }
  1395.             offset := -1
  1396.         ELSE
  1397.             offset := TEGetOffset(localPoint, fHTE) - 1;    { can use this directly, since we know we have styled TextEdit }
  1398.         IF offset >= 0 THEN TEGetStyle(offset, aStyle, lineHeight, fontAscent, fHTE);
  1399.         IF (offset >= 0) & (italic in aStyle.tsFace) THEN
  1400.             SetCursor(GetCursor(kSlantBeam)^^)
  1401.         ELSE
  1402.             BEGIN
  1403.             UseROMMap(TRUE);
  1404.             SetCursor(GetCursor(iBeamCursor)^^);
  1405.             END;
  1406.         SetRect(qdExtent, localPoint.h, localPoint.v,    { We could perhaps be more clever in }
  1407.                           localPoint.h, localPoint.v);    { setting this region, but I really  }
  1408.         RectRgn(cursorRgn, qdExtent);                    { don't think it matters much.         }
  1409.         DoSetCursor := TRUE;
  1410.         END
  1411.     ELSE
  1412.         DoSetCursor := FALSE;
  1413.     END;
  1414. {--------------------------------------------------------------------------------------------------}
  1415. {--------------------------------------------------------------------------------------------------}
  1416. {$ENDC} {MenuAccess}
  1417. {--------------------------------------------------------------------------------------------------}
  1418. {--------------------------------------------------------------------------------------------------}
  1419. {$IFC SubSuper}
  1420. {--------------------------------------------------------------------------------------------------}
  1421. {--------------------------------------------------------------------------------------------------}
  1422. {$S TEClose}
  1423.  
  1424. PROCEDURE TFullTEView.Free; OVERRIDE;
  1425.  
  1426.     BEGIN
  1427.     IF fAllowSubSuper THEN
  1428.         Handle(fSubSuperHandle) := DisposeIfHandle(fSubSuperHandle);
  1429.     INHERITED Free;
  1430.     END;
  1431.     
  1432. {--------------------------------------------------------------------------------------------------}
  1433. {$S FullTERes}
  1434.  
  1435. { Same as TTEView.DoKeyCommand, except FullTypingCommand instead of TypingCommand }
  1436.  
  1437. FUNCTION TFullTEView.OldDoKeyCommand(ch: Char; aKeyCode: INTEGER; VAR info: EventInfo): TCommand;
  1438.  
  1439.     VAR
  1440.         aTypingCommand:     TFullTETypingCommand;
  1441.         needNewCommand:     BOOLEAN;
  1442.         handledCharacter:    BOOLEAN;
  1443.  
  1444.     BEGIN
  1445.     OldDoKeyCommand := gNoChanges;
  1446.     handledCharacter := FALSE;
  1447.  
  1448.     IF IsViewEnabled & fAcceptsChanges THEN
  1449.         IF (ch >= ' ') | (ch = chReturn) | (ch = chBackspace) | (ch = chFwdDelete) THEN
  1450.             BEGIN
  1451.             IF Focus THEN;                                { Try to focus. }
  1452.             IF (ch <> chBackspace) & (ch <> chFwdDelete) & { Check max size for text, and that we're
  1453.                                                             }
  1454.                (fHTE^^.selStart = fHTE^^.selEnd) THEN    { …not running out of memory }
  1455.                 IF ((fMaxChars - GetHandleSize(fText)) < 1) | MemSpaceIsLow THEN
  1456.                     BEGIN
  1457.                     gApplication.Beep(0);
  1458.                     EXIT(OldDoKeyCommand);                 { Flush further keystrokes }
  1459.                     END;
  1460.  
  1461.             needNewCommand := (fFullTypingCommand = NIL);
  1462.             IF NOT needNewCommand THEN
  1463.                 needNewCommand := fFullTypingCommand.fCompleted;
  1464.  
  1465.             IF needNewCommand THEN
  1466.                 BEGIN
  1467.                 aTypingCommand := DoMakeFullTypingCommand(ch);
  1468.                 fFullTypingCommand := aTypingCommand;
  1469.                 OldDoKeyCommand := aTypingCommand;
  1470.                 END
  1471.             ELSE
  1472.                 fFullTypingCommand.AddCharacter(ch);
  1473.             handledCharacter := TRUE;
  1474.             END
  1475.  
  1476.         ELSE IF (ch >= chLeft) & (ch <= chDown) THEN
  1477.             BEGIN
  1478.             IF Focus THEN;                                { Try to focus. }
  1479.             DoneTyping;                                 { Like mousedown, further typing = new cmd }
  1480.             fSpecsChanged := TRUE;
  1481.             TEKey(ch, fHTE);
  1482.             ScrollSelectionIntoView;
  1483.             handledCharacter := TRUE;
  1484.             END;
  1485.  
  1486.     IF NOT handledCharacter THEN
  1487.         { Really want to call INHERITED INHERITED DoKeyCommand, but that's what }
  1488.         { will happen anyway ... }
  1489.         OldDoKeyCommand := INHERITED DoKeyCommand(ch, aKeyCode, info);
  1490.     END;
  1491.  
  1492. {--------------------------------------------------------------------------------------------------}
  1493. {$S FullTERes}
  1494.  
  1495. FUNCTION TFullTEView.DoMakeFullStyleCommand(aStyle: TextStyle; itsCmdNumber: CmdNumber;
  1496.                                     itsMode: INTEGER): TFullTEStyleCommand;
  1497.                                     
  1498. { This method is used rather than DoMakeStyleCommand only for font-size changes,
  1499.     and only if fAllowSubSuper is TRUE }
  1500.  
  1501.     VAR
  1502.         aTEStyleCommand:    TFullTEStyleCommand;        { use "Full" class }
  1503.  
  1504.     BEGIN
  1505.     New(aTEStyleCommand);
  1506.     FailNIL(aTEStyleCommand);
  1507.     aTEStyleCommand.ITEStyleCommand(SELF, aStyle, itsCmdNumber, itsMode);
  1508.     DoMakeFullStyleCommand := aTEStyleCommand;
  1509.     END;
  1510.  
  1511. {--------------------------------------------------------------------------------------------------}
  1512. {$S FullTERes}
  1513.  
  1514. FUNCTION TFullTEView.DoMakeFullTypingCommand(ch: Char): TFullTETypingCommand;
  1515.   
  1516.     VAR
  1517.         aTypingCommand:     TFullTETypingCommand;        { use "Full" class }
  1518.  
  1519.     BEGIN
  1520.     New(aTypingCommand);
  1521.     FailNIL(aTypingCommand);
  1522.     aTypingCommand.ITETypingCommand(SELF, ch);
  1523.     DoMakeFullTypingCommand := aTypingCommand;
  1524.     END;
  1525.  
  1526. {--------------------------------------------------------------------------------------------------}
  1527. {$S TENonRes}
  1528.  
  1529. PROCEDURE TFullTEView.DoneTyping; OVERRIDE;
  1530.  
  1531.     BEGIN
  1532.     IF fFullTypingCommand <> NIL THEN
  1533.         fFullTypingCommand.CompleteTyping;
  1534.     END;
  1535.  
  1536. {--------------------------------------------------------------------------------------------------}
  1537. {$S FullTERes}
  1538.  
  1539. PROCEDURE SubSuperDrawGlue; EXTERNAL;
  1540.  
  1541. PROCEDURE OldDrawProc(previousDrawProc: ProcPtr; theStart, length: INTEGER;
  1542.                         theText: CharsPtr; theTEPtr: TEPtr; theTEHdl: TEHandle); EXTERNAL;
  1543.  
  1544.  
  1545. PROCEDURE TFullTEView.NewSubSuperHandle;
  1546.  
  1547.     VAR        aHandle:            Handle;
  1548.             theProcPtr:            ProcPtr;
  1549.  
  1550.     BEGIN
  1551.     if fStyleType then
  1552.         BEGIN
  1553.         fAllowSubSuper := TRUE;
  1554.         aHandle := NewPermHandle((2 * SizeOf(SubSuperElement)) + 4 + SizeOf(SubOrSuper) +  SizeOf(ProcPtr));
  1555.         FailNil(aHandle);
  1556.         fSubSuperHandle := SubSuperHandle(aHandle);
  1557.         WITH fSubSuperHandle^^ DO
  1558.             BEGIN
  1559.             nRuns := 1;
  1560.             nullSubSuper := undefined;
  1561.             nullBaseSize := 0;
  1562.             runs[0].startChar := 0;
  1563.             runs[0].subSuper := normal;
  1564.             runs[0].baseSize := 0;
  1565.             runs[1].startChar := fHTE^^.teLength + 1;
  1566.             runs[1].subSuper := normal;
  1567.             runs[1].baseSize := 0;
  1568.             END;
  1569.         
  1570.         theProcPtr := @SubSuperDrawGlue;
  1571.         TECustomHook(intDrawHook, theProcPtr, fHTE);
  1572.         fSubSuperHandle^^.previousDrawProc := theProcPtr;
  1573.         
  1574.         END
  1575.     {$IFC qDebug}
  1576.     else
  1577.         ProgramBreak('Trying to give SubSuper handle to non-styled TEView!')
  1578.     {$ENDC}
  1579.     END;
  1580.  
  1581. {--------------------------------------------------------------------------------------------------}
  1582. {$S TENonRes}
  1583.  
  1584. PROCEDURE TFullTEView.StuffText(theText: Handle); OVERRIDE;
  1585.  
  1586.     BEGIN
  1587.     IF fHTE <> NIL THEN
  1588.         BEGIN
  1589.         INHERITED StuffText(theText);
  1590.         IF fAllowSubSuper THEN
  1591.             BEGIN
  1592.             SetPermHandleSize(Handle(fSubSuperHandle), (2 * SizeOf(SubSuperElement)) + 4 + SizeOf(SubOrSuper) +  SizeOf(ProcPtr));
  1593.             WITH fSubSuperHandle^^ DO
  1594.                 BEGIN
  1595.                 nRuns := 1;
  1596.                 nullSubSuper := undefined;
  1597.                 nullBaseSize := 0;
  1598.                 runs[0].startChar := 0;
  1599.                 runs[0].subSuper := normal;
  1600.                 runs[0].baseSize := 0;
  1601.                 runs[1].startChar := fHTE^^.teLength + 1;
  1602.                 runs[1].subSuper := normal;
  1603.                 runs[1].baseSize := 0;
  1604.                 END;
  1605.             END;
  1606.         END;
  1607.     END;
  1608.     
  1609. {--------------------------------------------------------------------------------------------------}
  1610. {$S TENonRes}
  1611.  
  1612. PROCEDURE TFullTEView.StuffSubSuper(theSubSuperHandle: SubSuperHandle; redraw: BOOLEAN);
  1613.  
  1614.     VAR
  1615.         oldNullSubSuper:         SubOrSuper;
  1616.         oldNullBaseSize:        INTEGER;
  1617.  
  1618.     BEGIN
  1619.     IF fAllowSubSuper & (fHTE <> NIL) THEN
  1620.         BEGIN
  1621.         WITH fSubSuperHandle^^ DO
  1622.             BEGIN
  1623.             oldNullSubSuper := nullSubSuper;
  1624.             oldNullBaseSize := nullBaseSize;
  1625.             END;
  1626.         SetSubSuper(0, MAXINT, theSubSuperHandle, redraw);
  1627.         WITH fSubSuperHandle^^ DO
  1628.             BEGIN
  1629.             nullSubSuper := oldNullSubSuper;
  1630.             nullBaseSize := oldNullBaseSize;
  1631.             END;
  1632.         END;
  1633.     END;
  1634.  
  1635. {--------------------------------------------------------------------------------------------------}
  1636. {$S FullTERes}
  1637.  
  1638. PROCEDURE NewDrawProc(theStart, length: INTEGER; theText: CharsPtr; theTEPtr: TEPtr; theTEHdl: TEHandle);
  1639.  
  1640.     VAR        theSubSuper:        SubSuperHandle;
  1641.             theStyleHandle:        TEStyleHandle;
  1642.             theEnd, thru, i:    INTEGER;
  1643.             changeBase:            BOOLEAN;
  1644.             theFontInfo:        FontInfo;
  1645.             shiftAmount:        INTEGER;
  1646.             offset:                INTEGER;
  1647.             halfSize:            INTEGER;
  1648.             
  1649.  
  1650.     BEGIN
  1651.     theStyleHandle := GetStylHandle(theTEHdl);
  1652.     FailNil(theStyleHandle);
  1653.     theSubSuper := SubSuperHandle(TFullTEView(theStyleHandle^^.teRefCon).fSubSuperHandle);
  1654.     FailNil(theSubSuper);
  1655.  
  1656.     offset := ORD(theText) - ORD(theTEHdl^^.hText^);
  1657.     theEnd := theStart + length;
  1658.     i := GetIndex(theSubSuper, theStart + offset);
  1659.     MoveHHi(Handle(theSubSuper));
  1660.     HLock(Handle(theSubSuper));
  1661.     WITH theSubSuper^^ DO
  1662.         REPEAT
  1663.             thru := MIN(theEnd + offset, runs[i + 1].startChar);
  1664.             changeBase := runs[i].subSuper <> normal;
  1665.             if changeBase then
  1666.                 BEGIN
  1667.                 halfSize := thePort^.txSize;
  1668.                 TextSize(runs[i].baseSize);
  1669.                 GetFontInfo(theFontInfo);
  1670.                 TextSize(halfSize);
  1671.                 if runs[i].subSuper = subscript then
  1672.                     shiftAmount := theFontInfo.descent
  1673.                 else
  1674.                     BEGIN
  1675.                     shiftAmount := theFontInfo.ascent;
  1676.                     GetFontInfo(theFontInfo);
  1677.                     shiftAmount := theFontInfo.ascent - shiftAmount;
  1678.                     END;
  1679.                 Move(0, shiftAmount);
  1680.                 END;
  1681.             OldDrawProc(previousDrawProc, theStart, thru - offset - theStart, theText, theTEPtr, theTEHdl);
  1682.             if changeBase then
  1683.                 Move(0, -shiftAmount);
  1684.             i := i + 1;
  1685.             theStart := thru - offset;
  1686.         UNTIL theStart >= theEnd;
  1687.     HUnlock(Handle(theSubSuper));
  1688.     END;
  1689.  
  1690. {--------------------------------------------------------------------------------------------------}
  1691. {$S FullTERes}
  1692.  
  1693. FUNCTION TFullTEView.GetSubSuperHandle: SubSuperHandle;
  1694.  
  1695.     VAR        i, runCount, firstRun, lastRun:        INTEGER;
  1696.             startOfSelection, endOfSelection:    INTEGER;
  1697.             me:                                    SubSuperHandle;
  1698.  
  1699.     BEGIN
  1700.     WITH fHTE^^,fSubSuperHandle^^ DO
  1701.         BEGIN
  1702.         startOfSelection := MAX(selStart, 0);
  1703.         endOfSelection := MIN(selEnd, runs[nRuns].startChar - 1);
  1704.         END;
  1705.     WITH fSubSuperHandle^^ DO
  1706.         if (startOfSelection < endOfSelection) | (nullSubSuper = undefined) then
  1707.             BEGIN
  1708.             firstRun := 0;
  1709.             WHILE runs[firstRun].startChar < startOfSelection DO
  1710.                 firstRun := firstRun + 1;
  1711.             if runs[firstRun].startChar > startOfSelection then
  1712.                 firstRun := firstRun - 1;
  1713.             lastRun := firstRun + 1;
  1714.             WHILE runs[lastRun].startChar < endOfSelection DO
  1715.                 lastRun := lastRun + 1;
  1716.             runCount := lastRun - firstRun + 1;
  1717.             END
  1718.         else
  1719.             runCount := 2;
  1720.  
  1721.     me := SubSuperHandle(NewPermHandle((runCount * SizeOf(SubSuperElement)) + 4 + SizeOf(SubOrSuper) + SizeOf(ProcPtr)));
  1722.     FailNil(me);
  1723.     WITH me^^ DO
  1724.         BEGIN
  1725.         nRuns := runCount - 1;
  1726.         nullSubSuper := undefined;
  1727.         nullBaseSize := 0;
  1728.         runs[0].startChar := 0;
  1729.         if (startOfSelection < endOfSelection) | (fSubSuperHandle^^.nullSubSuper = undefined) then
  1730.             BEGIN
  1731.             if firstRun = fSubSuperHandle^^.nRuns then firstRun := firstRun - 1;
  1732.             runs[0].subSuper := fSubSuperHandle^^.runs[firstRun].subSuper;
  1733.             runs[0].baseSize := fSubSuperHandle^^.runs[firstRun].baseSize;
  1734.             FOR i := 1 TO runCount - 2 DO
  1735.                 BEGIN
  1736.                 runs[i].startChar := 
  1737.                     fSubSuperHandle^^.runs[firstRun + i].startChar - startOfSelection;
  1738.                 runs[i].subSuper := fSubSuperHandle^^.runs[firstRun + i].subSuper;
  1739.                 runs[i].baseSize := fSubSuperHandle^^.runs[firstRun + i].baseSize;
  1740.                 END;
  1741.             END
  1742.         else
  1743.             BEGIN
  1744.             runs[0].subSuper := fSubSuperHandle^^.nullSubSuper;
  1745.             runs[0].baseSize := fSubSuperHandle^^.nullBaseSize;
  1746.             END;
  1747.         WITH runs[runCount - 1] DO
  1748.             BEGIN
  1749.             startChar := endOfSelection - startOfSelection + 1;
  1750.             subSuper := normal;
  1751.             baseSize := 0;
  1752.             END;
  1753.         END;
  1754.     GetSubSuperHandle := me;
  1755.     END;
  1756.     
  1757. {--------------------------------------------------------------------------------------------------}
  1758. {$S FullTERes}
  1759.  
  1760. PROCEDURE TFullTEView.DeleteSubSuperElement(index: INTEGER);
  1761.  
  1762.     VAR        newLength:        LONGINT;
  1763.     
  1764.     BEGIN
  1765.     WITH fSubSuperHandle^^ DO
  1766.         BEGIN
  1767.         FOR index := index TO nRuns - 1 DO
  1768.             runs[index] := runs[index + 1];
  1769.         nRuns := nRuns - 1;
  1770.         newLength := ((nRuns + 1) * SizeOf(SubSuperElement)) + 4 + SizeOf(SubOrSuper) + SizeOf(ProcPtr);
  1771.         END;
  1772.     SetPermHandleSize(Handle(fSubSuperHandle), newLength);
  1773.     END;
  1774.     
  1775. {--------------------------------------------------------------------------------------------------}
  1776. {$S FullTERes}
  1777.  
  1778. PROCEDURE TFullTEView.DeleteSubSuperChars(theStart, theEnd: INTEGER);
  1779.  
  1780.     VAR
  1781.         i, j, firstRun:        INTEGER;
  1782.         test:                BOOLEAN;
  1783.         theSubSuper:        SubOrSuper;
  1784.     
  1785.     BEGIN
  1786.     
  1787. { First, modify the offsets appropriately: }
  1788.     WITH fSubSuperHandle^^ DO
  1789.         BEGIN
  1790.         
  1791.         theStart := MAX(theStart, 0);
  1792.         theEnd := MIN(theEnd, runs[nRuns].startChar - 1);
  1793.         IF theStart >= theEnd THEN EXIT(DeleteSubSuperChars);
  1794.         
  1795.         IF NOT gNoScripts THEN
  1796.             BEGIN
  1797.             { Adjust for multi-byte characters... }
  1798.             WHILE CharByte(fText^, theStart) > 0 DO
  1799.                 theStart := theStart - 1;
  1800.             i := CharByte(fText^, theEnd - 1);
  1801.             WHILE (i <> 0) & (i <> 1) DO
  1802.                 BEGIN
  1803.                 theEnd := theEnd + 1;
  1804.                 i := CharByte(fText^, theEnd - 1);
  1805.                 END;
  1806.             END;
  1807.             
  1808.         firstRun := 0;
  1809.         WHILE runs[firstRun + 1].startChar <= theStart DO
  1810.             firstRun := firstRun + 1;
  1811.         i := firstRun + 1;
  1812.         WHILE runs[i].startChar < theEnd DO
  1813.             BEGIN
  1814.             runs[i].startChar := theEnd;
  1815.             i := i + 1;
  1816.             END;
  1817.         FOR i := firstRun + 1 TO nRuns DO
  1818.             WITH runs[i] DO
  1819.                 startChar := startChar - (theEnd - theStart);
  1820.         nullSubSuper := runs[firstRun].subSuper;
  1821.         nullBaseSize := runs[firstRun].baseSize;
  1822.         END;
  1823.  
  1824. { Second, clean up the results as necessary: }
  1825.     i := firstRun;
  1826.     WHILE (i < fSubSuperHandle^^.nRuns) & (fSubSuperHandle^^.nRuns > 1) DO
  1827.         WITH fSubSuperHandle^^ DO
  1828.             BEGIN
  1829.             j := runs[i + 1].startChar;
  1830.             IF i = (nRuns - 1) THEN j := j - 1;
  1831.             IF runs[i].startChar >= j THEN
  1832.                 DeleteSubSuperElement(i)
  1833.             ELSE IF (i > 0) & (runs[i].subSuper = runs[i - 1].subSuper) THEN
  1834.                 BEGIN
  1835.                 runs[i - 1].baseSize := MAX(runs[i - 1].baseSize, runs[i].baseSize);
  1836.                 DeleteSubSuperElement(i);
  1837.                 END
  1838.             ELSE
  1839.                 i := i + 1;
  1840.             END;
  1841.     END;
  1842.  
  1843. {--------------------------------------------------------------------------------------------------}
  1844. {$S FullTERes}
  1845.  
  1846. PROCEDURE TFullTEView.InsertSubSuperChars(insertionPoint, length: INTEGER; theSubSuperHandle: SubSuperHandle);
  1847.     
  1848.     VAR        i:        INTEGER;
  1849.     
  1850.     BEGIN
  1851. { First, modify the offsets appropriately: }
  1852.     WITH fSubSuperHandle^^ DO
  1853.         BEGIN
  1854.         insertionPoint := MIN(insertionPoint, runs[nRuns].startChar - 1);
  1855.         i := 1;
  1856.         WHILE runs[i].startChar < insertionPoint DO
  1857.             i := i + 1;
  1858.         if runs[i].startChar = insertionPoint then i := i + 1;
  1859.         FOR i := i TO nRuns DO
  1860.             WITH runs[i] DO
  1861.                 startChar := startChar + length;
  1862.         END;
  1863. { And now: }    
  1864.     SetSubSuper(insertionPoint, insertionPoint + length, theSubSuperHandle, kDontRedraw);
  1865.     END;
  1866.     
  1867. {--------------------------------------------------------------------------------------------------}
  1868. {$S FullTERes}
  1869.  
  1870. FUNCTION TFullTEView.ContinuousSubSuper(theStart, theEnd: INTEGER; VAR which: SubOrSuper; VAR theBaseSize: INTEGER): BOOLEAN;
  1871.  
  1872.     VAR        i:        INTEGER;        
  1873.     
  1874.     BEGIN
  1875.     if fSubSuperHandle = NIL then
  1876.         BEGIN
  1877.         ContinuousSubSuper := TRUE;
  1878.         which := normal;
  1879.         theBaseSize := -1; {ie, undefined}
  1880.         END
  1881.     else if (theStart >= theEnd) & (fSubSuperHandle^^.nullSubSuper <> undefined) then
  1882.         BEGIN
  1883.         ContinuousSubSuper := TRUE;
  1884.         which := fSubSuperHandle^^.nullSubSuper;
  1885.         theBaseSize := fSubSuperHandle^^.nullBaseSize;
  1886.         END
  1887.     else
  1888.         BEGIN
  1889.         WITH fSubSuperHandle^^ DO
  1890.             BEGIN
  1891.             i := 0;
  1892.             WHILE runs[i].startChar < theStart DO
  1893.                 i := i + 1;
  1894.             if (theStart >= theEnd) | (runs[i].startChar > theStart) then
  1895.                 i := MAX(i - 1, 0);
  1896.             if runs[i + 1].startChar >= theEnd then
  1897.                 BEGIN
  1898.                 ContinuousSubSuper := TRUE;
  1899.                 which := runs[i].subSuper;
  1900.                 theBaseSize := runs[i].baseSize;
  1901.                 END
  1902.             else
  1903.                 ContinuousSubSuper := FALSE;
  1904.             END;
  1905.         END;
  1906.     END;
  1907.  
  1908. {--------------------------------------------------------------------------------------------------}
  1909. {$S FullTERes}
  1910.  
  1911. PROCEDURE TFullTEView.GetSubSuper(theStart: INTEGER; VAR theSubSuper: SubOrSuper; theBaseSize: INTEGER);
  1912.     
  1913.     BEGIN
  1914.     WITH fSubSuperHandle^^.runs[GetIndex(fSubSuperHandle, theStart)] DO
  1915.         BEGIN
  1916.         theSubSuper := subSuper;
  1917.         theBaseSize := baseSize;
  1918.         END;
  1919.     END;
  1920.     
  1921. {--------------------------------------------------------------------------------------------------}
  1922. {$S FullTERes}
  1923.  
  1924. PROCEDURE TFullTEView.SetSubSuper(theStart, theEnd: INTEGER; theSubSuperHandle: SubSuperHandle; redraw: BOOLEAN);
  1925.  
  1926.     VAR        i, j:        INTEGER;
  1927.             aSubSuper:    SubOrSuper;
  1928.     
  1929.  
  1930.     PROCEDURE SetOneSubSuper(theStart, theEnd: INTEGER; which: SubOrSuper; theBaseSize: INTEGER);
  1931.     
  1932.         VAR        theStyleHandle:        TEStyleHandle;
  1933.                 i:                    INTEGER;
  1934.                 prevSubSuper:        SubOrSuper;
  1935.                 prevBaseSize:        INTEGER;
  1936.                 
  1937.         
  1938.         PROCEDURE InsertElement(index, theStart: INTEGER; which: SubOrSuper; theBaseSize: INTEGER);
  1939.         
  1940.             VAR
  1941.                 newLength:            LONGINT;
  1942.                 i:                    INTEGER;
  1943.                 
  1944.             BEGIN
  1945.             newLength := ((fSubSuperHandle^^.nRuns + 2) * SizeOf(SubSuperElement)) + 4 + SizeOf(SubOrSuper) + SizeOf(ProcPtr);
  1946.             SetPermHandleSize(Handle(fSubSuperHandle), newLength);
  1947.             WITH fSubSuperHandle^^ DO
  1948.                 BEGIN
  1949.                 nRuns := nRuns + 1;
  1950.                 FOR i := nRuns DOWNTO index + 1 DO        { ¿should do one BlockMove instead .... }
  1951.                     runs[i] := runs[i - 1];
  1952.                 runs[index].startChar := theStart;
  1953.                 runs[index].subSuper := which;
  1954.                 runs[index].baseSize := theBaseSize;
  1955.                 END;
  1956.             END;
  1957.         
  1958.         
  1959.         BEGIN    {SetOneSubSuper}
  1960.     
  1961.         i := 0;
  1962.         WITH fSubSuperHandle^^ DO
  1963.             WHILE runs[i].startChar < theStart DO
  1964.                 i := i + 1;        
  1965.  
  1966.         if fSubSuperHandle^^.runs[i].startChar = theStart then
  1967.             WITH fSubSuperHandle^^.runs[i] DO
  1968.                 BEGIN
  1969.                 prevSubSuper := subSuper;
  1970.                 subSuper := which;
  1971.                 prevBaseSize := baseSize;
  1972.                 baseSize := theBaseSize;
  1973.                 i := i + 1;
  1974.                 END
  1975.         else
  1976.             BEGIN
  1977.             WITH fSubSuperHandle^^.runs[i - 1] DO
  1978.                 BEGIN
  1979.                 prevSubSuper := subSuper;
  1980.                 prevBaseSize := baseSize;
  1981.                 END;
  1982.             if prevSubSuper <> which then
  1983.                 BEGIN
  1984.                 InsertElement(i, theStart, which, theBaseSize);
  1985.                 i := i + 1;
  1986.                 END;
  1987.             END;
  1988.  
  1989.         WHILE fSubSuperHandle^^.runs[i].startChar < theEnd DO
  1990.             BEGIN
  1991.             WITH fSubSuperHandle^^.runs[i] DO
  1992.                 BEGIN
  1993.                 prevSubSuper := subSuper;
  1994.                 prevBaseSize := MAX(baseSize, prevBaseSize);
  1995.                 END;
  1996.             DeleteSubSuperElement(i);
  1997.             END;
  1998.  
  1999.         WITH fSubSuperHandle^^ DO
  2000.             if (runs[i].startChar > theEnd) & (theEnd < runs[nRuns].startChar - 1) then
  2001.                 if prevSubSuper <> which then
  2002.                     BEGIN
  2003.                     InsertElement(i, theEnd, prevSubSuper, prevBaseSize);
  2004.                     i := i + 1;
  2005.                     END;
  2006.         
  2007.         i := 1;
  2008.         WHILE i < fSubSuperHandle^^.nRuns DO
  2009.             WITH fSubSuperHandle^^ DO
  2010.                 if runs[i].subSuper = runs[i - 1].subSuper then
  2011.                     BEGIN
  2012.                     runs[i - 1].baseSize := MAX(runs[i - 1].baseSize, runs[i].baseSize);
  2013.                     DeleteSubSuperElement(i);
  2014.                     END
  2015.                 else
  2016.                     i := i + 1;
  2017.                     
  2018.         END;    {SetOneSubSuper}
  2019.             
  2020.         
  2021.     BEGIN    {SetSubSuper}
  2022.  
  2023. {$IFC qDebug}
  2024.     if fSubSuperHandle = NIL then
  2025.         ProgramBreak('fSubSuperHandle is NIL!');
  2026. {$ENDC}
  2027.  
  2028.     theStart := MAX(theStart, 0);
  2029.     WITH fSubSuperHandle^^ DO
  2030.         theEnd := MIN(theEnd, runs[nRuns].startChar - 1);
  2031.         
  2032.     IF theSubSuperHandle = NIL THEN
  2033.         if fSubSuperHandle^^.nullSubSuper <> undefined then
  2034.             BEGIN
  2035.             WITH fSubSuperHandle^^ DO
  2036.                 SetOneSubSuper(theStart, theEnd, nullSubSuper, nullBaseSize);
  2037.             WITH fSubSuperHandle^^ DO
  2038.                 BEGIN
  2039.                 nullSubSuper := undefined;
  2040.                 nullBaseSize := 0;
  2041.                 END
  2042.             END
  2043.         else
  2044.             WITH fSubSuperHandle^^.runs[GetIndex(fSubSuperHandle, theStart - 1)] DO
  2045.                 SetOneSubSuper(theStart, theEnd, subSuper, baseSize)
  2046.             
  2047.     ELSE
  2048.         if theStart >= theEnd then
  2049.             WITH fSubSuperHandle^^ DO
  2050.                 BEGIN
  2051.                 nullSubSuper := theSubSuperHandle^^.runs[0].subSuper;
  2052.                 nullBaseSize := theSubSuperHandle^^.runs[0].baseSize;
  2053.                 END
  2054.         else
  2055.             BEGIN
  2056.             MoveHHi(Handle(theSubSuperHandle));
  2057.             HLock(Handle(theSubSuperHandle));
  2058.             WITH theSubSuperHandle^^ DO
  2059.                 FOR i := 0 TO nRuns - 1 DO
  2060.                     BEGIN
  2061.                     j := runs[i + 1].startChar;
  2062.                     IF i = nRuns - 1 THEN j := j - 1;
  2063.                     SetOneSubSuper(theStart + runs[i].startChar, 
  2064.                                    theStart + j,
  2065.                                    runs[i].subSuper, runs[i].baseSize);
  2066.                     END;
  2067.             HUnlock(Handle(theSubSuperHandle));
  2068.             WITH fSubSuperHandle^^ DO
  2069.                 BEGIN
  2070.                 nullSubSuper := undefined;
  2071.                 nullBaseSize := 0
  2072.                 END
  2073.             END;
  2074.         
  2075.     if redraw then ForceRedraw;
  2076.     fSpecsChanged := TRUE;
  2077.     END;
  2078.  
  2079. {--------------------------------------------------------------------------------------------------}
  2080. {$S FullTERes}
  2081.  
  2082. FUNCTION TFullTEView.DoSubSuperCommand(aCmdNumber: CmdNumber): TTECommand;
  2083.  
  2084.     VAR
  2085.         aSubSuperCommand:    TFullTESubSuperCommand;
  2086.  
  2087.     BEGIN
  2088.     New(aSubSuperCommand);
  2089.     FailNIL(aSubSuperCommand);
  2090.     aSubSuperCommand.ITFullTESubSuperCommand(SELF, aCmdNumber);
  2091.     DoSubSuperCommand := aSubSuperCommand;
  2092.     END;
  2093.  
  2094. {--------------------------------------------------------------------------------------------------}
  2095. {$S TEClipboard}
  2096.  
  2097. FUNCTION TFullTEView.GivePasteData(aDataHandle: Handle; dataType: ResType): LONGINT; OVERRIDE;
  2098.  
  2099.     VAR
  2100.         oldStart:            INTEGER;
  2101.         oldEnd:             INTEGER;
  2102.         aSize:                LONGINT;
  2103.         aHandle:            Handle;
  2104.         err:                OSErr;
  2105.         savedPerm:            BOOLEAN;
  2106.         fi:                 FailInfo;
  2107.  
  2108.     PROCEDURE HdlGivePasteFailed(error: OSErr; message: LONGINT);
  2109.  
  2110.         BEGIN
  2111.         DisposIfHandle(aHandle);
  2112.         END;
  2113.  
  2114.     BEGIN
  2115.     
  2116.     IF dataType <> kSubSuperClipType THEN
  2117.         GivePasteData := INHERITED GivePasteData(aDataHandle, dataType)
  2118.     ELSE
  2119.         BEGIN
  2120.     
  2121.         aSize := 0;
  2122.         savedPerm := FALSE;
  2123.         aHandle := NIL;
  2124.         CatchFailures(fi, HdlGivePasteFailed);
  2125.         
  2126.         IF fAllowSubSuper THEN
  2127.             BEGIN        
  2128.  
  2129.             WITH fHTE^^ DO
  2130.                 BEGIN
  2131.                 oldStart := selStart;
  2132.                 oldEnd := selEnd;
  2133.                 END;
  2134.             SetSelect(0, MAXINT, fHTE);
  2135.             aHandle := Handle(GetSubSuperHandle);
  2136.             SetSelect(oldStart, oldEnd, fHTE);
  2137.  
  2138.             IF aHandle <> NIL THEN
  2139.                 BEGIN
  2140.                 aSize := GetHandleSize(aHandle);
  2141.                 IF aDataHandle <> NIL THEN
  2142.                     BEGIN
  2143.                     savedPerm := PermAllocation(TRUE);
  2144.                     MoveHHi(aHandle);                { Try to prevent fragmentation, in case }
  2145.                     HLock(aHandle);                 { Can't move while we're copying it! }
  2146.  
  2147.                     err := PtrToXHand(aHandle^,     { Copy styles into user-supplied handle }
  2148.                                       aDataHandle, aSize);
  2149.                     HUnlock(aHandle);                { Okay for it to move again }
  2150.                     savedPerm := PermAllocation(savedPerm);
  2151.                     IF err <> noErr THEN
  2152.                         Failure(phStylesTooBig, phStylesTooBig + msgAlert);
  2153.                     END;
  2154.                 DisposIfHandle(aHandle);
  2155.                 END
  2156.             ELSE IF aDataHandle <> NIL THEN
  2157.                 Failure(phStylesTooBig, phStylesTooBig + msgAlert);
  2158.                 
  2159.             END;
  2160.             
  2161.         FailSpaceIsLow;
  2162.         Success(fi);
  2163.         GivePasteData := aSize;
  2164.         END;
  2165.         
  2166.     END;
  2167.  
  2168. {--------------------------------------------------------------------------------------------------}
  2169. {$S TENonRes}
  2170.  
  2171. PROCEDURE TFullTEView.WriteToDeskScrap; OVERRIDE;
  2172.  
  2173.     BEGIN
  2174.     INHERITED WriteToDeskScrap;
  2175.  
  2176.     IF fAllowSubSuper THEN
  2177.         FailOSErr(PutDeskScrapData(kSubSuperClipType, Handle(fSubSuperHandle)));
  2178.     END;
  2179.  
  2180. {--------------------------------------------------------------------------------------------------}
  2181. {--------------------------------------------------------------------------------------------------}
  2182. {$ENDC} {SubSuper}
  2183. {--------------------------------------------------------------------------------------------------}
  2184. {--------------------------------------------------------------------------------------------------}
  2185. {$IFC qDebug}
  2186. {$S TEFields}
  2187.  
  2188. PROCEDURE TFullTEView.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  2189.                          fieldType: INTEGER)); OVERRIDE;
  2190.  
  2191.     BEGIN
  2192.     DoToField('TFullTEView', NIL, bClass);
  2193.     DoToField('fSelAnchor',            @fSelAnchor,    bInteger);
  2194.     DoToField('fUpDown',            @fUpDown,        bBoolean);
  2195.     DoToField('fUpDownH',            @fUpDownH,        bInteger);
  2196.     DoToField('fDoubleAnchor',        @fDoubleAnchor,    bInteger);
  2197.     DoToField('fDoubleStart',        @fDoubleStart,    bInteger);
  2198.     DoToField('fDoubleEnd',            @fDoubleEnd,    bInteger);
  2199.     {$IFC MenuAccess}    
  2200.     DoToField('fMenuFont',            @fMenuFont,        bBoolean);
  2201.     DoToField('fMenuSize',            @fMenuSize,        bBoolean);
  2202.     DoToField('fMenuStyle',            @fMenuStyle,    bBoolean);
  2203.     DoToField('fMenuJust',            @fMenuJust,        bBoolean);
  2204.     DoToField('fMenuUpDown',        @fMenuUpDown,    bBoolean);
  2205.     DoToField('fAllowedStyles',        @fAllowedStyles, bInteger);
  2206.     {$ENDC}
  2207.     {$IFC SubSuper}
  2208.     DoToField('fFullTypingCommand',    @fFullTypingCommand,    bObject);
  2209.     DoToField('fAllowSubSuper',        @fAllowSubSuper,        bBoolean);
  2210.     DoToField('fSubSuperHandle',    @fSubSuperHandle,        bHandle);
  2211.     {$ENDC}
  2212.     INHERITED Fields(DoToField);
  2213.     END;
  2214.  
  2215. {$ENDC}
  2216. {--------------------------------------------------------------------------------------------------}
  2217. {--------------------------------------------------------------------------------------------------}
  2218. {$IFC SubSuper}
  2219. {--------------------------------------------------------------------------------------------------}
  2220. {--------------------------------------------------------------------------------------------------}
  2221. {$S TEOpen}
  2222.  
  2223. PROCEDURE TFullSubSuperTEView.ITEView(itsDocument: TDocument; itsSuperView: TView; itsLocation, itsSize: VPoint;
  2224.                           itsHDeterminer, itsVDeterminer: SizeDeterminer; itsInset: Rect;
  2225.                           itsTextStyle: TextStyle; itsJustification: INTEGER; itsStyleType,
  2226.                           itsAutoWrap: BOOLEAN); OVERRIDE;
  2227.     BEGIN
  2228.     INHERITED ITEView(itsDocument, itsSuperView, itsLocation, itsSize,
  2229.                         itsHDeterminer, itsVDeterminer, itsInset, itsTextStyle,
  2230.                         itsJustification, itsStyleType, itsAutoWrap);
  2231.     if fStyleType then NewSubSuperHandle;
  2232.     END;
  2233. {--------------------------------------------------------------------------------------------------}
  2234. {$S TEOpen}
  2235.  
  2236. PROCEDURE TFullSubSuperTEView.IRes(itsDocument: TDocument; itsSuperView: TView; VAR itsParams: Ptr); OVERRIDE;
  2237.  
  2238.     BEGIN
  2239.     INHERITED IRes(itsDocument, itsSuperView, itsParams);
  2240.     NewSubSuperHandle;
  2241.     END;
  2242.     
  2243. {--------------------------------------------------------------------------------------------------}
  2244. {--------------------------------------------------------------------------------------------------}
  2245. {$ENDC} {SubSuper}
  2246. {--------------------------------------------------------------------------------------------------}
  2247. {--------------------------------------------------------------------------------------------------}
  2248. {$S TEOpen}
  2249.  
  2250. PROCEDURE TFullTEMouseCommand.ITEMouseCommand(itsTEView: TFullTEView; shift: BOOLEAN);
  2251.  
  2252.     VAR            nonAnchor:        INTEGER;
  2253.  
  2254.     BEGIN
  2255.     ICommand(cTextCommand, NIL, itsTEView, itsTEView.GetScroller(TRUE));
  2256.     fCanUndo := FALSE;
  2257.     fCausesChange := FALSE;
  2258.     fTEView := itsTEView;
  2259.     fShift := shift;
  2260.     fWordSelect := FALSE;
  2261.     fSelAnchor := itsTEView.fSelAnchor;
  2262.     fNewAnchor := fSelAnchor;
  2263.     WITH itsTEView.fHTE^^ DO
  2264.         BEGIN
  2265.         fOrigStart := selStart;
  2266.         fOrigEnd := selEnd;
  2267.         END;
  2268. {$IFC SubSuper}
  2269.     WITH itsTEView DO
  2270.         if fAllowSubSuper then
  2271.             WITH fSubSuperHandle^^ DO
  2272.                 BEGIN
  2273.                 nullSubSuper := undefined;
  2274.                 nullBaseSize := 0;
  2275.                 END;
  2276. {$ENDC}
  2277.     END;
  2278.  
  2279. {--------------------------------------------------------------------------------------------------}
  2280. {$S FullTERes}
  2281.  
  2282.  
  2283. PROCEDURE TFullTEMouseCommand.TrackFeedback(anchorPoint, nextPoint: VPoint;
  2284.                                         turnItOn, mouseDidMove: BOOLEAN); OVERRIDE;                                        
  2285.     BEGIN
  2286.     { default behavior would have drawn a gray rectangle }
  2287.     END;
  2288.  
  2289. {--------------------------------------------------------------------------------------------------}
  2290. {$S FullTERes}
  2291.  
  2292. FUNCTION TFullTEMouseCommand.TrackMouse(aTrackPhase: TrackPhase;
  2293.                     VAR anchorPoint, previousPoint, nextPoint: VPoint;
  2294.                     mouseDidMove: BOOLEAN): TCommand; OVERRIDE;
  2295.     VAR
  2296.             msePos, newStart, newEnd:                    INTEGER;
  2297.     
  2298.     
  2299.     PROCEDURE ResetAnchor;
  2300.         BEGIN
  2301.         if fSelAnchor < 0 then                {previous double-click}
  2302.             if newStart = fOrigStart then
  2303.                 fNewAnchor := fOrigStart
  2304.             else
  2305.                 fNewAnchor := fOrigEnd
  2306.         END;
  2307.  
  2308.     BEGIN
  2309.     if aTrackPhase = trackRelease then
  2310.         BEGIN
  2311.         fTEView.fSelAnchor := fNewAnchor;
  2312.         TrackMouse := gNoChanges;
  2313.         END
  2314.     else
  2315.         BEGIN
  2316.         TrackMouse := SELF;
  2317.         
  2318.         if ClickLoopForTTEView then;
  2319.         
  2320.         msePos := fTEView.PtToOffset(nextPoint);
  2321.  
  2322.         if aTrackPhase = trackPress then
  2323.             BEGIN
  2324.             if gClickCount = 1 then
  2325.                 BEGIN
  2326.                 WITH fTEView DO                {save current info in case this}
  2327.                     BEGIN                    {turns out to be a double-click}
  2328.                     fDoubleAnchor := fSelAnchor;
  2329.                     fDoubleStart := fOrigStart;
  2330.                     fDoubleEnd := fOrigEnd;
  2331.                     END;
  2332.                 if fShift then
  2333.                     BEGIN
  2334.                     newStart := MIN(msePos, fOrigStart);
  2335.                     newEnd := MAX(msePos, fOrigEnd);
  2336.                     ResetAnchor;
  2337.                     END
  2338.                 else
  2339.                     BEGIN
  2340.                     newStart := msePos;
  2341.                     newEnd := msePos;
  2342.                     fOrigStart := msePos;
  2343.                     fOrigEnd := msePos;
  2344.                     fNewAnchor := msePos;
  2345.                     END
  2346.                 END
  2347.             else if gClickCount >= 2 then
  2348.                 BEGIN
  2349.                 WITH fTEView DO                {restore saved info}
  2350.                     BEGIN
  2351.                     fSelAnchor := fDoubleAnchor;
  2352.                     fNewAnchor := fSelAnchor;
  2353.                     fOrigStart := fDoubleStart;
  2354.                     fOrigEnd := fDoubleEnd;
  2355.                     END;
  2356.                 fWordSelect := TRUE;
  2357.                 if gClickCount = 2 then
  2358.                     BEGIN
  2359.                     if NOT fTEView.WordBounds(msePos, newStart, newEnd) then
  2360.                         if fTEView.WordBounds(msePos-1, newStart, newEnd) then;
  2361.                     END
  2362.                 else
  2363.                     BEGIN
  2364.                     if NOT fTEView.TripleBounds(msePos, newStart, newEnd) then
  2365.                         if fTEView.TripleBounds(msePos-1, newStart, newEnd) then;
  2366.                     END;
  2367.                 newEnd := newEnd + 1;
  2368.                 if fShift then
  2369.                     BEGIN
  2370.                     newStart := MIN(newStart, fOrigStart);
  2371.                     newEnd := MAX(newEnd, fOrigEnd);
  2372.                     ResetAnchor;
  2373.                     END
  2374.                 else
  2375.                     BEGIN
  2376.                     fOrigStart := newStart;
  2377.                     fOrigEnd := newEnd;
  2378.                     fSelAnchor := -1;
  2379.                     fNewAnchor := -1;
  2380.                     END
  2381.                 END
  2382.             END
  2383.         else {trackMove}
  2384.             BEGIN
  2385.             if fWordSelect then
  2386.                 BEGIN
  2387.                 if gClickCount = 2 then
  2388.                     BEGIN
  2389.                     if NOT fTEView.WordBounds(msePos, newStart, newEnd) then
  2390.                         if fTEView.WordBounds(msePos-1, newStart, newEnd) then;
  2391.                     END
  2392.                 else
  2393.                     BEGIN
  2394.                     if NOT fTEView.TripleBounds(msePos, newStart, newEnd) then
  2395.                         if fTEView.TripleBounds(msePos-1, newStart, newEnd) then;
  2396.                     END;
  2397.                 newEnd := newEnd + 1;
  2398.                 if fShift then
  2399.                     if newEnd >= fOrigEnd then
  2400.                         BEGIN
  2401.                         newStart := fOrigStart;
  2402.                         newEnd := MAX(newEnd, fOrigEnd);
  2403.                         END
  2404.                     else
  2405.                         BEGIN
  2406.                         newStart := MIN(newStart, fOrigStart);
  2407.                         newEnd := fOrigEnd;
  2408.                         END
  2409.                 else
  2410.                     BEGIN
  2411.                     newStart := MIN(newStart, fOrigStart);
  2412.                     newEnd := MAX(newEnd, fOrigEnd);
  2413.                     ResetAnchor;
  2414.                     END
  2415.                 END
  2416.             else
  2417.                 BEGIN
  2418.                 newStart := MIN(msePos, fOrigStart);
  2419.                 newEnd := MAX(msePos, fOrigEnd);
  2420.                 if fShift then ResetAnchor;
  2421.                 END;
  2422.             END;
  2423.         fTEView.DrawSelection(newStart, newEnd);
  2424.         END;
  2425.     END;
  2426.  
  2427. {--------------------------------------------------------------------------------------------------}
  2428. {$IFC qDebug}
  2429. {$S TEFields}
  2430.  
  2431. PROCEDURE TFullTEMouseCommand.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  2432.                                  fieldType: INTEGER)); OVERRIDE;
  2433.  
  2434.     BEGIN
  2435.     DoToField('TFullTEMouseCommand', NIL,        bClass);
  2436.     DoToField('fTEView',     @fTEView,         bObject);
  2437.     DoToField('fShift',        @fShift,        bBoolean);
  2438.     DoToField('fWordSelect',@fWordSelect,    bBoolean);
  2439.     DoToField('fSelAnchor',    @fSelAnchor,    bInteger);
  2440.     DoToField('fNewAnchor',    @fNewAnchor,    bInteger);
  2441.     DoToField('fOrigStart',    @fOrigStart,    bInteger);
  2442.     DoToField('fOrigEnd',    @fOrigEnd,        bInteger);
  2443.     INHERITED Fields(DoToField);
  2444.     END;
  2445.  
  2446. {$ENDC}
  2447. {--------------------------------------------------------------------------------------------------}
  2448. {--------------------------------------------------------------------------------------------------}
  2449. {$S FullTERes}
  2450.  
  2451. FUNCTION IsBlank(pText: Ptr; offset: Integer; VAR length: Integer): BOOLEAN;
  2452.  
  2453.     VAR
  2454.         i:    Integer;
  2455.         
  2456.     BEGIN
  2457.     if gNoScripts then
  2458.         BEGIN
  2459.         IsBlank := CHAR(PTR(Ord4(pText) + offset)^) = ' ';
  2460.         length := 1;
  2461.         END
  2462.     else
  2463.         BEGIN
  2464.         i := CharType(pText, offset);
  2465.         IsBlank := BAND(i, $0F00) = smPunctBlank;
  2466.         if CharByte(pText, offset) = 0 then
  2467.             length := 1
  2468.         else
  2469.             length := 2;
  2470.         END
  2471.     END;
  2472.  
  2473. {--------------------------------------------------------------------------------------------------}
  2474. {$S TESelCommand}
  2475.  
  2476. PROCEDURE TFullTECommand.ITECommand(itsTEView: TTEView; itsCmdNumber: CmdNumber; itsSaveText: BOOLEAN); OVERRIDE;
  2477.  
  2478.     VAR
  2479.         origStart, origEnd,    lWordStart, lWordEnd,
  2480.                             rWordStart, rWordEnd:    Integer;
  2481.         spaceLeft, spaceRight:                        Boolean;
  2482.         i:                                            Integer;
  2483. {$IFC SubSuper}
  2484.         fi:                 FailInfo;
  2485.  
  2486.     PROCEDURE HdlInitFailed(error: OSErr; message: LONGINT);
  2487.  
  2488.         BEGIN
  2489.         Free;
  2490.         END;
  2491. {$ENDC}
  2492.  
  2493.     BEGIN
  2494. { ********************* implement intelligent Cut/Clear/Copy ***************** }
  2495.     if (itsCmdNumber = cCut) | (itsCmdNumber = cClear) | (itsCmdNumber = cCopy) then
  2496.         WITH itsTEView.fHTE^^ DO
  2497.         BEGIN
  2498.         gFullWordLeft := FALSE;
  2499.         gFullWordRight := FALSE;
  2500.         origStart := selStart;
  2501.         origEnd := selEnd;
  2502.         if origStart < origEnd then
  2503.             BEGIN
  2504.  
  2505.             if TFullTEView(itsTEView).WordBounds(origStart, lWordStart, lWordEnd)
  2506.                     & (lWordStart = origStart) & (lWordEnd < origEnd) then
  2507.                 BEGIN
  2508.                 gFullWordLeft := TRUE;
  2509.                 spaceLeft := (lWordStart > 0) & IsBlank(hText^, lWordStart-1, i);
  2510.                 END
  2511.             else
  2512.                 spaceLeft := FALSE;        
  2513.  
  2514.             if TFullTEView(itsTEView).WordBounds(origEnd - 1, rWordStart, rWordEnd)
  2515.                     & (rWordStart >= origStart) & (rWordEnd = origEnd - 1) then
  2516.                 BEGIN
  2517.                 gFullWordRight := TRUE;
  2518.                 rWordEnd := rWordEnd + 1;
  2519.                 spaceRight := (rWordEnd < teLength) & IsBlank(hText^, rWordEnd, i);
  2520.                 END
  2521.             else
  2522.                 spaceRight := FALSE;
  2523.  
  2524.             if itsCmdNumber <> cCopy then
  2525.                 if spaceLeft &
  2526.                     (gFullWordRight | (origEnd >= teLength) |
  2527.                         IsBlank(hText^, origEnd, i)) then
  2528.                     selStart := selStart - 1
  2529.                 else if spaceRight & 
  2530.                     (gFullWordLeft | (origStart <= 0) |
  2531.                         IsBlank(hText^, origStart-1, i)) then
  2532.                     selEnd := selEnd + 1;
  2533.                 
  2534.             END;
  2535.         END;
  2536.             
  2537. {$IFC SubSuper}
  2538.     fOldSubSuper := NIL;
  2539.     fNewSubSuper := NIL;
  2540. {$ENDC}
  2541.  
  2542.     INHERITED ITECommand(itsTEView, itsCmdNumber, itsSaveText);
  2543.  
  2544. {$IFC SubSuper}
  2545.     IF TFullTEView(itsTEView).fAllowSubSuper THEN
  2546.         BEGIN
  2547.         CatchFailures(fi, HdlInitFailed);
  2548.         fOldSubSuper := TFullTEView(itsTEView).GetSubSuperHandle;
  2549.         FailNIL(fOldSubSuper);
  2550.         Success(fi);
  2551.         END;
  2552. {$ENDC}
  2553.  
  2554.     END;
  2555. {--------------------------------------------------------------------------------------------------}
  2556. {$IFC SubSuper}
  2557. {--------------------------------------------------------------------------------------------------}
  2558. {$S TEDoCommand}
  2559.  
  2560. PROCEDURE TFullTECommand.BanishOldText; OVERRIDE;
  2561.  
  2562.     BEGIN
  2563.     IF TFullTEView(fTEView).fAllowSubSuper & (fOldEnd > fOldStart) THEN
  2564.         TFullTEView(fTEView).DeleteSubSuperChars(fOldStart, fOldEnd);
  2565.     INHERITED BanishOldText;
  2566.     END;
  2567.  
  2568. {--------------------------------------------------------------------------------------------------}
  2569. {$S TEDoCommand}
  2570.  
  2571. PROCEDURE TFullTECommand.Free; OVERRIDE;
  2572.  
  2573.     BEGIN
  2574.     DisposIfHandle(fOldSubSuper);
  2575.     DisposIfHandle(fNewSubSuper);
  2576.     INHERITED Free;
  2577.     END;
  2578.  
  2579. {--------------------------------------------------------------------------------------------------}
  2580. {$S TEDoCommand}
  2581.  
  2582. PROCEDURE TFullTECommand.InstallNewText; OVERRIDE;
  2583.  
  2584.     BEGIN
  2585.     IF fNewEnd > fNewStart THEN
  2586.         BEGIN
  2587.         if TFullTEView(fTEView).fAllowSubSuper then
  2588.             TFullTEView(fTEView).InsertSubSuperChars(fOldStart, fNewEnd - fNewStart, fNewSubSuper);
  2589.         INHERITED InstallNewText;
  2590.         END;
  2591.     END;
  2592.  
  2593. {--------------------------------------------------------------------------------------------------}
  2594. {$S TEDoCommand}
  2595.  
  2596. PROCEDURE TFullTECommand.RemoveAdditions; OVERRIDE;
  2597.  
  2598.     BEGIN
  2599.     IF TFullTEView(fTEView).fAllowSubSuper & (fNewText <> NIL) THEN
  2600.         TFullTEView(fTEView).DeleteSubSuperChars(fNewStart, fNewEnd);
  2601.     INHERITED RemoveAdditions;
  2602.     END;
  2603.  
  2604. {--------------------------------------------------------------------------------------------------}
  2605. {$S TEDoCommand}
  2606.  
  2607. PROCEDURE TFullTECommand.ReviveDeletions; OVERRIDE;
  2608.  
  2609.     VAR        i, position, length:        INTEGER;
  2610.  
  2611.     BEGIN
  2612.     if TFullTEView(fTEView).fAllowSubSuper & (GetHandleSize(fOldText) > 0) then
  2613.         TFullTEView(fTEView).InsertSubSuperChars(fOldStart, fOldEnd - fOldStart, fOldSubSuper);
  2614.     INHERITED ReviveDeletions;
  2615.     END;
  2616.  
  2617. {--------------------------------------------------------------------------------------------------}
  2618. {$ENDC} {SubSuper}
  2619. {--------------------------------------------------------------------------------------------------}
  2620. {$IFC qDebug}
  2621. {$S TEFields}
  2622.  
  2623. PROCEDURE TFullTECommand.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  2624.                          fieldType: INTEGER)); OVERRIDE;
  2625.  
  2626.     BEGIN
  2627.     DoToField('TFullTECommand', NIL, bClass);
  2628. {$IFC SubSuper}
  2629.     DoToField('fOldSubSuper',    @fOldSubSuper,    bHandle);
  2630.     DoToField('fNewSubSuper',    @fNewSubSuper,    bHandle);
  2631. {$ENDC}
  2632.     INHERITED Fields(DoToField);
  2633.     END;
  2634.  
  2635. {$ENDC}
  2636. {--------------------------------------------------------------------------------------------------}
  2637. {--------------------------------------------------------------------------------------------------}
  2638. {$S TESelCommand}
  2639.  
  2640. PROCEDURE TFullTECutCopyCommand.ITECutCopyCommand(itsTEView: TTEView; itsCmdNumber: CmdNumber);
  2641.  
  2642. {no change from TTECutCopyCommand}
  2643.  
  2644.     BEGIN
  2645.     fClipCreated := FALSE;
  2646.     ITECommand(itsTEView, itsCmdNumber, TRUE);
  2647.     fChangesClipboard := TRUE;
  2648.     fCausesChange := itsCmdNumber <> cCopy;
  2649.     END;
  2650.  
  2651. {--------------------------------------------------------------------------------------------------}
  2652. {$S TEDoCommand}
  2653.  
  2654. PROCEDURE TFullTECutCopyCommand.Free; OVERRIDE;
  2655.  
  2656. {change from TTECutCopyCommand for sub/superscripts}
  2657.  
  2658.     BEGIN
  2659.     IF fClipCreated THEN
  2660.         BEGIN
  2661.         fOldText := NIL;
  2662.     {$IFC SubSuper}
  2663.         fOldSubSuper := NIL;
  2664.     {$ENDC}
  2665.         END;
  2666.     INHERITED Free;
  2667.     END;
  2668.  
  2669. {--------------------------------------------------------------------------------------------------}
  2670. {$S TEDoCommand}
  2671.  
  2672. PROCEDURE TFullTECutCopyCommand.DoIt; OVERRIDE;
  2673.  
  2674. {changes from TTECutCopyCommand to handle sub/superscripts}
  2675.  
  2676.     VAR
  2677.     {$IFC SubSuper}
  2678.         clipTEView:            TFullSubSuperTEView;
  2679.     {$ELSEC}
  2680.         clipTEView:         TTEView;
  2681.     {$ENDC}
  2682.         clipHere:            BOOLEAN;
  2683.         fi:                 FailInfo;
  2684.         clipStyle:            TextStyle;
  2685.         itsSize:            VPoint;
  2686.         itsMargins:         Rect;
  2687.  
  2688.     PROCEDURE HdlClipFailed(error: OSErr; message: LONGINT);
  2689.  
  2690.         BEGIN
  2691.         FreeIfObject(clipTEView);
  2692.         clipTEView := NIL;
  2693.         END;
  2694.  
  2695.     BEGIN                                                {TTECutCopyCommand.DoIt}
  2696.     IF fTEView.Focus THEN;                                {??? What if Focus fails}
  2697.  
  2698.     SetTextStyle(clipStyle, applFont, [],                { Initial style same as virgin TEView }
  2699.                  12, gRGBBlack);
  2700.  
  2701.     SetVPt(itsSize, 100, 50);                            { An arbitrary initial size. }
  2702.     SetRect(itsMargins, 10, 8, 10, 0);                    { No bottom margin. }
  2703.  
  2704.     New(clipTEView);                                    { Create a new view for the clipboard }
  2705.     FailNIL(clipTEView);
  2706.     WITH fTEView DO
  2707.         clipTEView.ITEView(NIL, NIL,                    { Initialize view }
  2708.                            gZeroVPt, itsSize, sizeSuperView, sizeVariable, itsMargins, clipStyle,
  2709.                            teJustLeft, fStyleType, fAutoWrap);
  2710.     clipTEView.fAcceptsChanges := FALSE;                { This is a read-only view }
  2711.  
  2712.     CatchFailures(fi, HdlClipFailed);                    { Cut can eat into temp memory so users can
  2713.                                                          }
  2714.     { …rescue text from overweight documents }
  2715.     IF NOT fCausesChange THEN                            { If Copy-ing, assure there's enough room }
  2716.         FailSpaceIsLow;
  2717.     Success(fi);
  2718.     
  2719.     clipTEView.StuffText(fOldText);
  2720.     FailSpaceIsLow;
  2721.  
  2722.     {??? GOT TO FIGURE OUT SOME WAY TO PRE-FLIGHT THIS! ??????????????????????????????????? }
  2723.     IF clipTEView.fStyleType = kWithStyle THEN            { If record has style }
  2724.         SetStylScrap(0, MAXINT, fOldStyles,             { …then put in the styles }
  2725.                      FALSE, clipTEView.fHTE);
  2726.     FailSpaceIsLow;
  2727.  
  2728. {$IFC SubSuper}
  2729.     WITH TFullTEView(fTEView) DO
  2730.         IF fAllowSubSuper THEN                            { If record has sub/superscripts }
  2731.             clipTEView.SetSubSuper(0, MAXINT, fOldSubSuper, kDontRedraw);
  2732.  
  2733.     FailSpaceIsLow;
  2734. {$ENDC}
  2735.  
  2736.     clipTEView.fFreeText := TRUE;                        { Let TEView know it has to free the text }
  2737.  
  2738.     gApplication.ClaimClipboard(clipTEView);            { Okay to claim (will call RecalcText!) }
  2739.  
  2740.     fClipCreated := TRUE;                                { We be done }
  2741.     DoMainFunction;                                     { Do the actual cut/copy }
  2742.  
  2743.     {$IFC qDebug}
  2744.     IF pTEIntenseDebugging THEN
  2745.         BEGIN
  2746.         DumpTERecord(clipTEView.fHTE);
  2747.         DumpTTECommand(SELF);
  2748.         END;
  2749.     {$ENDC}
  2750.     END;
  2751.  
  2752. {--------------------------------------------------------------------------------------------------}
  2753. {$S TEDoCommand}
  2754.  
  2755. PROCEDURE TFullTECutCopyCommand.ReviveDeletions; OVERRIDE;
  2756.  
  2757. {no change from TTECutCopyCommand}
  2758.  
  2759.     BEGIN
  2760.     IF fCmdNumber = cCut THEN
  2761.         INHERITED ReviveDeletions;                        { Don't do it for COPY }
  2762.     END;
  2763.  
  2764. {--------------------------------------------------------------------------------------------------}
  2765. {$IFC qDebug}
  2766. {$S TEFields}
  2767.  
  2768. PROCEDURE TFullTECutCopyCommand.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  2769.                                                        fieldType: INTEGER)); OVERRIDE;
  2770. {no change from TTECutCopyCommand}
  2771.  
  2772.     BEGIN
  2773.     DoToField('TFullTECutCopyCommand', NIL, bClass);
  2774.     DoToField('fClipCreated', @fClipCreated, bBoolean);
  2775.     INHERITED Fields(DoToField);
  2776.     END;
  2777.  
  2778. {$ENDC}
  2779. {--------------------------------------------------------------------------------------------------}
  2780. {--------------------------------------------------------------------------------------------------}
  2781. {$S TESelCommand}
  2782.  
  2783. PROCEDURE TFullTEPasteCommand.ITEPasteCommand(itsTEView: TFullTEView);
  2784.  
  2785. { **** section added for intelligent paste **** }
  2786. {  & other changes for sub/superscript handling    }
  2787.  
  2788. { We can't use TEPaste because it clobbers the DeskScrap; the text would be recoverable
  2789.   from the special TextEdit Scrap, but other types of non-TEXT scrap are permanently
  2790.   lost, it seems }
  2791.  
  2792.     VAR
  2793.         savedPerm:            BOOLEAN;
  2794.         newLength:            INTEGER;
  2795.         newStyleLen:        LONGINT;
  2796.         newText:            Handle;
  2797.         newStyles:            StScrpHandle;
  2798. {$IFC SubSuper}
  2799.         newSubSuperLen:        LONGINT;
  2800.         newSubSuper:        SubSuperHandle;
  2801. {$ENDC}
  2802.         dataType:            ResType;
  2803.         fi:                 FailInfo;
  2804.         
  2805.         space:                    STRING[1];
  2806.         long:                    LONGINT;
  2807.         i, j:                    INTEGER;
  2808.         addLeft, delLeft,
  2809.         addRight, delRight:        INTEGER;
  2810.  
  2811.     PROCEDURE HdlPasteFailed(error: OSErr; message: LONGINT);
  2812.  
  2813.         BEGIN
  2814.         IF newText <> fNewText THEN                     { newText is assigned to fNewText }
  2815.             newText := DisposeIfHandle(newText);        { …so avoid disposing twice. }
  2816.         IF newStyles <> fNewStyles THEN                 { Ditto for newStyles. }
  2817.             Handle(newStyles) := DisposeIfHandle(newStyles);
  2818. {$IFC SubSuper}
  2819.         IF newSubSuper <> fNewSubSuper THEN            { and for newSubSuperHandle. }
  2820.             Handle(newSubSuper) := DisposeIfHandle(newSubSuper);
  2821. {$ENDC}
  2822.         Free;
  2823.         END;
  2824.  
  2825.     BEGIN
  2826.     ITECommand(itsTEView, cPaste, TRUE);                { Perform stock initializations }
  2827.  
  2828.     savedPerm := FALSE;
  2829.  
  2830.     newStyleLen := 0;                                    { Assume there are no new styles }
  2831.     newStyles := NIL;
  2832.     newText := NIL;
  2833.  
  2834. {$IFC SubSuper}
  2835.     newSubSuperLen := 0;
  2836.     newSubSuper := NIL;                                    { Ditto for sub/super }
  2837. {$ENDC}
  2838.  
  2839.     CatchFailures(fi, HdlPasteFailed);
  2840.  
  2841.     newText := NewPermHandle(0);                        { Create handle to receive clipboard data }
  2842.     FailNIL(newText);
  2843.     IF itsTEView.fStyleType = kWithStyle THEN
  2844.         BEGIN
  2845.         newStyles := StScrpHandle(NewPermHandle(0));    { Same for handle to receive style info }
  2846.         FailNIL(newStyles);
  2847.         END;
  2848. {$IFC SubSuper}
  2849.     IF itsTEView.fAllowSubSuper THEN
  2850.         BEGIN
  2851.         newSubSuper := SubSuperHandle(NewPermHandle(0)); { Same for handle to receive sub/super info }
  2852.         FailNil(newSubSuper);
  2853.         END;
  2854. {$ENDC}
  2855.  
  2856.     newLength := gApplication.GetDataToPaste(newText, dataType);
  2857.     
  2858. { **************************** intelligent paste: **************************** }
  2859.  
  2860.     if newLength > 0 then
  2861.         {$IFC qDebug}
  2862.         IF dataType <> 'TEXT' THEN
  2863.             ProgramBreak('TEPasteCommandNew given some non-text from clipboard')
  2864.         ELSE
  2865.         {$ENDC}
  2866.         BEGIN
  2867.         addLeft := 0;
  2868.         delLeft := 0;
  2869.         addRight := 0;
  2870.         delRight := 0;
  2871.         space := ' ';
  2872.         if gFullWordLeft then
  2873.             if TFullTEView(fTEView).WordBounds(fHTE^^.selStart-1, i, j) then
  2874.                 BEGIN
  2875.                 if NOT IsBlank(newText^, 0, i) then
  2876.                     BEGIN
  2877.                     addLeft := 1;
  2878.                     long := Munger(newText, 0, NIL,0, @space[1],1);
  2879.                     FailMemError;
  2880.                     newLength := newLength + 1;
  2881.                     END;
  2882.                 END
  2883.             else
  2884.                 if IsBlank(newText^, 0, i) then
  2885.                     BEGIN
  2886.                     delLeft := i;
  2887.                     long := Munger(newText, 0, NIL,i, @space[1],0);
  2888.                     FailMemError;
  2889.                     newLength := newLength - i;
  2890.                     END;
  2891.                 
  2892.         if gFullWordRight then
  2893.             if TFullTEView(fTEView).WordBounds(fHTE^^.selEnd, i, j) then
  2894.                 BEGIN
  2895.                 if NOT IsBlank(newText^, newLength - 1, i) then
  2896.                     BEGIN
  2897.                     addRight := 1;
  2898.                     long := Munger(newText, newLength, NIL, 0, @space[1], 1);
  2899.                     FailMemError;
  2900.                     newLength := newLength + 1;
  2901.                     END;
  2902.                 END
  2903.             else
  2904.                 if IsBlank(newText^, newLength-1, i) then
  2905.                     BEGIN
  2906.                     delRight := i;
  2907.                     long := Munger(newText, newLength-1, NIL,i, @space[1],0);
  2908.                     FailMemError;
  2909.                     newLength := newLength - i;
  2910.                     END;
  2911.         END;
  2912. { **************************************************************************** }
  2913.  
  2914.     IF newLength > 0 THEN
  2915.         BEGIN
  2916.         {$IFC qDebug}
  2917.         IF dataType <> 'TEXT' THEN
  2918.             ProgramBreak('TEPasteCommand given some non-text from clipboard')
  2919.         ELSE
  2920.         {$ENDC}
  2921.             BEGIN                                        { Prime "new" values }
  2922.             fNewText := newText;
  2923.             fNewStart := fHTE^^.selStart;
  2924.             fNewEnd := fNewStart + newLength;
  2925.             fTextPad := newLength - (fOldEnd - fOldStart);
  2926.  
  2927.             IF itsTEView.fStyleType = kWithStyle THEN
  2928.                 BEGIN
  2929.                 newStyleLen := gClipView.GivePasteData(Handle(newStyles), 'styl');
  2930. {$IFC SubSuper}
  2931.                 IF itsTEView.fAllowSubSuper THEN
  2932.                 newSubSuperLen := gClipView.GivePasteData(Handle(newSubSuper), kSubSuperClipType);
  2933. {$ENDC}
  2934.  
  2935. { **************************************************************************** }
  2936.  
  2937.                 IF newStyleLen > 0 then 
  2938.                 WITH newStyles^^ DO
  2939.                 { Note: the scrpStyleTab is indexed [0..scrpNStyles-1], not [0..scrpNStyles] }
  2940.                     BEGIN
  2941.                     if addLeft > 0 then
  2942.                         FOR i := 1 TO scrpNStyles - 1 DO
  2943.                             scrpStyleTab[i].scrpStartChar := scrpStyleTab[i].scrpStartChar + addLeft
  2944.             
  2945.                     else if delLeft > 0 then
  2946.                         BEGIN
  2947.                         j := 0;
  2948.                         WHILE (j < scrpNStyles - 1) & (scrpStyleTab[j + 1].scrpStartChar <= delLeft) DO
  2949.                             j := j + 1;
  2950.                         if j > 0 then
  2951.                             BEGIN
  2952.                             FOR i := 0 TO scrpNStyles - 1 - j DO
  2953.                                 scrpStyleTab[i] := scrpStyleTab[i + j];
  2954.                             scrpStyleTab[0].scrpStartChar := 0;
  2955.                             scrpNStyles := scrpNStyles - j;
  2956.                             END;
  2957.                         FOR i := 1 TO scrpNStyles - 1 DO
  2958.                             WITH scrpStyleTab[i] DO
  2959.                                 scrpStartChar := scrpStartChar - delLeft;
  2960.                         END;
  2961.  
  2962.                     if delRight > 0 then
  2963.                         BEGIN
  2964.                         j := scrpNStyles - 1;
  2965.                         WHILE scrpStyleTab[j].scrpStartChar >= newLength DO
  2966.                             j := j - 1;
  2967.                         scrpNStyles := j + 1;
  2968.                         END;
  2969.                     END;
  2970. {$IFC SubSuper}
  2971.                 IF newSubSuperLen > 0 then 
  2972.                 WITH newSubSuper^^ DO
  2973.                     BEGIN
  2974.                     if addLeft > 0 then
  2975.                         FOR i := 1 TO nRuns DO
  2976.                             runs[i].startChar := runs[i].startChar + addLeft
  2977.             
  2978.                     else if delLeft > 0 then
  2979.                         BEGIN
  2980.                         j := 1;
  2981.                         WHILE runs[j].startChar <= delLeft DO
  2982.                             j := j + 1;
  2983.                         if j > 1 then
  2984.                             BEGIN
  2985.                             FOR i := 0 TO nRuns - j DO
  2986.                                 runs[i] := runs[i + j];
  2987.                             runs[0].startChar := 0;
  2988.                             nRuns := nRuns - j;
  2989.                             END;
  2990.                         FOR i := 1 TO nRuns DO
  2991.                             runs[i].startChar := runs[i].startChar - delLeft;
  2992.                         END;
  2993.                         
  2994.                     if addRight > 0 then
  2995.                         runs[nRuns].startChar :=
  2996.                             runs[nRuns].startChar + addRight
  2997.                             
  2998.                     else if delRight > 0 then
  2999.                         BEGIN
  3000.                         j := nRuns - 1;
  3001.                         WHILE runs[j].startChar >= newLength DO
  3002.                             j := j - 1;
  3003.                         nRuns := j + 1;
  3004.                         runs[nRuns].startChar := newLength + 1;
  3005.                         END;
  3006.                     END;
  3007. {$ENDC}
  3008. { **************************************************************************** }
  3009.  
  3010.                 IF newStyleLen > 0 THEN
  3011.                     BEGIN
  3012.                     fNewStyles := newStyles;
  3013.                     fStylePad :=                        { Difference between old and new styles }
  3014.                       newStyleLen - fStylePad;
  3015.                     END
  3016.                 ELSE
  3017.                     Handle(newStyles) := DisposeIfHandle(newStyles);
  3018. {$IFC SubSuper}
  3019.                 IF newSubSuperLen > 0 THEN
  3020.                     fNewSubSuper := newSubSuper
  3021.                 ELSE
  3022.                     Handle(newSubSuper) := DisposeIfHandle(newSubSuper);
  3023. {$ENDC}
  3024.                 END;
  3025.  
  3026.             SetPermHandleSize(fPadding, MAX(fTextPad + fStylePad, 0));
  3027.  
  3028.             FailSpaceIsLow;
  3029.             END;
  3030.         END
  3031.     ELSE
  3032.         BEGIN
  3033.         newText := DisposeIfHandle(newText);
  3034.         Handle(newStyles) := DisposeIfHandle(Handle(newStyles));
  3035. {$IFC SubSuper}
  3036.         Handle(newSubSuper) := DisposeIfHandle(newSubSuper);
  3037. {$ENDC}
  3038.         END;
  3039.     Success(fi);
  3040.     END;
  3041.  
  3042. {--------------------------------------------------------------------------------------------------}
  3043. {$IFC qDebug}
  3044. {$S FullTERes}
  3045.  
  3046. PROCEDURE TFullTEPasteCommand.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  3047.                                                      fieldType: INTEGER)); OVERRIDE;
  3048.  
  3049.     BEGIN
  3050.     DoToField('TFullTEPasteCommand', NIL, bClass);
  3051.     INHERITED Fields(DoToField);
  3052.     END;
  3053. {$ENDC}
  3054. {--------------------------------------------------------------------------------------------------}
  3055. {--------------------------------------------------------------------------------------------------}
  3056. {$IFC MenuAccess}
  3057. {--------------------------------------------------------------------------------------------------}
  3058. {$S FullTERes}
  3059.  
  3060. PROCEDURE TJustCommand.IJustCommand(itsTEView: TTEView; itsNewJust: INTEGER);
  3061.  
  3062.     BEGIN
  3063.     ICommand(cJustChange, itsTEView.fDocument, NIL, NIL);
  3064.     fTEView := itsTEView;
  3065.     fOldJust := itsTEView.fJustification;
  3066.     fNewJust := itsNewJust;
  3067.     END;
  3068.  
  3069. {--------------------------------------------------------------------------------------------------}
  3070. {$S FullTERes}
  3071.  
  3072. PROCEDURE TJustCommand.DoIt; OVERRIDE;
  3073.  
  3074.     BEGIN
  3075.     fTEView.SetJustification(fNewJust, kRedraw);
  3076.     END;
  3077.  
  3078. {--------------------------------------------------------------------------------------------------}
  3079. {$S FullTERes}
  3080.  
  3081. PROCEDURE TJustCommand.RedoIt; OVERRIDE;
  3082.  
  3083.     BEGIN
  3084.     DoIt;
  3085.     END;
  3086.  
  3087. {--------------------------------------------------------------------------------------------------}
  3088. {$S FullTERes}
  3089.  
  3090. PROCEDURE TJustCommand.UndoIt; OVERRIDE;
  3091.  
  3092.     BEGIN
  3093.     fTEView.SetJustification(fOldJust, kRedraw);
  3094.     END;
  3095.  
  3096. {--------------------------------------------------------------------------------------------------}
  3097. {$IFC qDebug}
  3098. {$S AFields}
  3099.  
  3100. PROCEDURE TJustCommand.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  3101.                                                   fieldType: INTEGER)); OVERRIDE;
  3102.  
  3103.     BEGIN
  3104.     DoToField('TJustCommand', NIL, bClass);
  3105.     DoToField('fTEView', @fTEView, bObject);
  3106.     DoToField('fOldJust', @fOldJust, bInteger);
  3107.     DoToField('fNewJust', @fNewJust, bInteger);
  3108.     INHERITED Fields(DoToField);
  3109.     END;
  3110. {$ENDC}
  3111. {--------------------------------------------------------------------------------------------------}
  3112. {$ENDC} {MenuAccess}
  3113. {--------------------------------------------------------------------------------------------------}
  3114. {--------------------------------------------------------------------------------------------------}
  3115. {$IFC SubSuper}
  3116. {--------------------------------------------------------------------------------------------------}
  3117. {$S FullTERes}
  3118.  
  3119. PROCEDURE TFullTETypingCommand.ITETypingCommand(itsTEView: TTEView; itsFirstChar: Char);
  3120.  
  3121. { no changes from TTETypingCommand }
  3122.  
  3123.     VAR
  3124.         fi:                 FailInfo;
  3125.  
  3126.     PROCEDURE HdlInitFailed(error: OSErr; message: LONGINT);
  3127.  
  3128.         BEGIN
  3129.         Free;
  3130.         END;
  3131.  
  3132.     BEGIN
  3133.     ITECommand(itsTEView, cTyping, TRUE);
  3134.  
  3135.     CatchFailures(fi, HdlInitFailed);
  3136.  
  3137.     fNewStart := fHTE^^.selStart;                        { Start and end are the same }
  3138.     fNewEnd := fNewStart;
  3139.  
  3140.     fNewText := NewPermHandle(0);                        { Allocate an empty block for text }
  3141.     FailNIL(fNewText);
  3142.  
  3143.     fCompleted := FALSE;                                { We've only just begun… }
  3144.     fFirstChar := itsFirstChar;                         { Save character for Doit }
  3145.     Success(fi);
  3146.     END;
  3147.  
  3148. {--------------------------------------------------------------------------------------------------}
  3149. {$S FullTERes}
  3150.  
  3151. PROCEDURE TFullTETypingCommand.Free; OVERRIDE;
  3152.  
  3153. { change fTypingCommand to fFullTypingCommand }
  3154.  
  3155.     BEGIN
  3156.     IF TFullTEView(fTEView).fFullTypingCommand = SELF THEN
  3157.         TFullTEView(fTEView).fFullTypingCommand := NIL;
  3158.     INHERITED Free;
  3159.     END;
  3160.  
  3161. {--------------------------------------------------------------------------------------------------}
  3162. {$S FullTERes}
  3163.  
  3164. PROCEDURE TFullTETypingCommand.DoNormalChar(aChar: Char);
  3165.  
  3166. { no changes from TTETypingCommand }
  3167.  
  3168.     BEGIN
  3169.     FailOSErr(PtrAndHand(Ptr(SUCC(ORD(@aChar))),        { Append char to end of fNewText }
  3170.                          fNewText, 1));
  3171.     fNewEnd := SUCC(fNewEnd);                            { Bump both end of "selection" }
  3172.     fTextPad := SUCC(fTextPad);                         { …and padding value }
  3173.  
  3174.     SetHandleSize(fPadding,                             { This SetHandleSize can't grow the handle,
  3175.                                                          }
  3176.                   MAX( - (fTextPad + fStylePad), 0));    { …so it shouldn't fail. }
  3177.     FailMemError;
  3178.     END;
  3179.  
  3180. {--------------------------------------------------------------------------------------------------}
  3181. { User has backspaced to the left of the original starting point.  First, copy the
  3182.  character (which may be more than one byte long if we are using a non-Roman script)
  3183.  to a temporary buffer.  The assumption is that no character will ever be longer
  3184.  than four bytes.  Sorry, folks, MacApp does not support typing in any script with
  3185.  more than 4 billion characters.
  3186.   Next, copy the character to the front of fOldText, and adjust fOldStart, fNewStart,
  3187.  and fNewEnd.  Note that we do NOT check for MemSpaceIsLow, since we want to let the
  3188.  user delete characters. }
  3189. {$S FullTERes}
  3190.  
  3191. PROCEDURE TFullTETypingCommand.BkSpcLeft(theText: Handle; curStart: INTEGER);
  3192.  
  3193.     TYPE
  3194.         TSPtr                = ^TextStyle;
  3195.  
  3196.     VAR
  3197.         savedSize:            INTEGER;
  3198.         theHeight:            INTEGER;
  3199.         theAscent:            INTEGER;
  3200.         oldSize:            LONGINT;
  3201.         whoCares:            LONGINT;
  3202.         aTextStyle:         TSPtr;
  3203.         savedChar:            PACKED ARRAY [0..3] OF Char;
  3204.         delStyle:            TextStyle;
  3205.         delSubSuper:        SubOrSuper;
  3206.         delBaseSize:        INTEGER;
  3207.         {$IFC qDebug}
  3208.         savedPerm:            BOOLEAN;
  3209.         {$ENDC}
  3210.  
  3211.     BEGIN
  3212.     savedSize := 1;
  3213.     IF qNeedsScriptManager | gConfiguration.hasScriptManager THEN
  3214.         WHILE CharByte(theText^, curStart - savedSize) > 0 DO
  3215.             savedSize := SUCC(savedSize);
  3216.     curStart := curStart - savedSize;
  3217.  
  3218.     {$IFC qDebug}
  3219.     IF savedSize > 4 THEN
  3220.         ProgramBreak('Character > 4 bytes');
  3221.     {$ENDC}
  3222.     IF savedSize = 1 THEN                                { Slight speed optimization for normal case
  3223.                                                          }
  3224.     {$Push} {$R-}
  3225.         savedChar[0] := CharsHandle(theText)^^[curStart]
  3226.         {$Pop}
  3227.     ELSE
  3228.         BlockMove(Ptr(ORD(theText^) + curStart), @savedChar, savedSize);
  3229.  
  3230.     IF fTEView.fStyleType = kWithStyle THEN             { Only do this if styles are around }
  3231.         BEGIN
  3232.         TEGetStyle(curStart, delStyle,                    { Get the style of the deleted character }
  3233.                    theHeight, theAscent, fHTE);         { (1 or 4 bytes, it's all only one style) }
  3234.  
  3235.         IF NOT EqualBlocks(@delStyle,                    { If style doesn't match first in the list }
  3236.                            @fOldStyles^^.scrpStyleTab[0].scrpFont, SIZEOF(TextStyle)) THEN
  3237.             BEGIN                                        { …then insert new style at head of list }
  3238.             fTEView.fSpecsChanged := TRUE;                { User backspaced into new style! }
  3239.  
  3240.             oldSize :=                                    { Make room for the new style element }
  3241.               GetHandleSize(Handle(fOldStyles));
  3242.             SetHandleSize(Handle(fOldStyles), oldSize + SIZEOF(ScrpSTElement));
  3243.             FailMemError;
  3244.             fStylePad := fStylePad + SIZEOF(ScrpSTElement);
  3245.  
  3246.             {$Push} {$H-}
  3247.             WITH fOldStyles^^.scrpStyleTab[0] DO
  3248.                 BlockMove(@scrpStartChar,                { Move entire array up one element's size }
  3249.                           Ptr(ORD(@scrpStartChar) + SIZEOF(ScrpSTElement)), oldSize -
  3250.                           SIZEOF(fOldStyles^^.scrpNStyles));
  3251.             {$Pop}
  3252.  
  3253.             fOldStyles^^.scrpNStyles :=                 { One more style }
  3254.               SUCC(fOldStyles^^.scrpNStyles);
  3255.             WITH fOldStyles^^.scrpStyleTab[0] DO
  3256.                 BEGIN
  3257.                 scrpHeight := theHeight;                { Fill in the blanks }
  3258.                 scrpAscent := theAscent;
  3259.                 aTextStyle := TSPtr(@scrpFont);
  3260.                 aTextStyle^ := delStyle;
  3261.                 END;
  3262.             END;
  3263.  
  3264.         WITH fOldStyles^^.scrpStyleTab[0] DO
  3265.             scrpStartChar := { PRED(scrpStartChar);    }    { Regardless, back off offset by one }
  3266.                             scrpStartChar - savedSize;    { <- correction! }
  3267.         END;
  3268.  
  3269. {******************************************************************************}
  3270.     IF TFullTEView(fTEView).fAllowSubSuper THEN 
  3271.         BEGIN
  3272.         TFullTEView(fTEView).GetSubSuper(curStart, delSubSuper, delBaseSize);
  3273.         IF delSubSuper <> fOldSubSuper^^.runs[0].subSuper THEN
  3274.             BEGIN
  3275.             fTEView.fSpecsChanged := TRUE;                { User backspaced into new sub/super! }
  3276.  
  3277.             oldSize :=                                    { Make room for the new subsuper element }
  3278.               GetHandleSize(Handle(fOldSubSuper));
  3279.             SetHandleSize(Handle(fOldSubSuper), oldSize + SIZEOF(SubSuperElement));
  3280.             FailMemError;
  3281.  
  3282.             {$Push} {$H-}
  3283.             WITH fOldSubSuper^^.runs[0] DO
  3284.                 BlockMove(@startChar,                { Move entire array up one element's size }
  3285.                           Ptr(ORD(@startChar) + SIZEOF(SubSuperElement)), oldSize -
  3286.                           SIZEOF(fOldSubSuper^^.previousDrawProc) -
  3287.                           SIZEOF(fOldSubSuper^^.nRuns) - SIZEOF(fOldSubSuper^^.nullSubSuper) -
  3288.                           SIZEOF(fOldSubSuper^^.nullBaseSize));
  3289.             {$Pop}
  3290.  
  3291.             WITH fOldSubSuper^^ DO
  3292.                 nRuns := SUCC(nRuns);
  3293.             fOldSubSuper^^.runs[0].subSuper := delSubSuper;
  3294.             fOldSubSuper^^.runs[0].baseSize := delBaseSize;
  3295.             END;
  3296.  
  3297.         WITH fOldSubSuper^^.runs[0] DO
  3298.             startChar := startChar - savedSize;        { Regardless, back off offset by one }
  3299.         END;
  3300. {******************************************************************************}
  3301.  
  3302.     SetHandleSize(fPadding, GetHandleSize(fOldText) + savedSize + fStylePad);
  3303.     FailMemError;
  3304.     whoCares := Munger(fOldText, 0, NIL, 0, @savedChar, savedSize);
  3305.     FailMemError;
  3306.     fOldStart := curStart;                                { Treat this as though original selection }
  3307.     fNewStart := curStart;                                { …had included this character }
  3308.     fNewEnd := curStart;
  3309.     fTextPad := fTextPad - savedSize;
  3310.     END;
  3311.  
  3312. {--------------------------------------------------------------------------------------------------}
  3313. {$S FullTERes}
  3314.  
  3315. PROCEDURE TFullTETypingCommand.BkSpcRight(theText: Handle; curStart: INTEGER);
  3316.  
  3317. { no change from TTETypingCommand }
  3318.  
  3319.     VAR
  3320.         savedSize:            INTEGER;
  3321.  
  3322.     BEGIN
  3323.     savedSize := 1;
  3324.     IF qNeedsScriptManager | gConfiguration.hasScriptManager THEN
  3325.         WHILE CharByte(theText^, curStart - savedSize) > 0 DO
  3326.             savedSize := SUCC(savedSize);
  3327.     SetHandleSize(fPadding, MAX( - (fTextPad - savedSize + fStylePad), 0));
  3328.     FailMemError;
  3329.     fNewEnd := fNewEnd - savedSize;
  3330.     fTextPad := fTextPad - savedSize;
  3331.  
  3332.     SetHandleSize(fNewText, fNewEnd - fNewStart);        { Shouldn't fail as we're only shrinking it
  3333.                                                          }
  3334.     FailMemError;
  3335.     END;
  3336.  
  3337. {--------------------------------------------------------------------------------------------------}
  3338. { Forward delete (TTETypingCommand) courtesy of: Larry Goldman.  Used by permission. }
  3339. {$S FullTERes}
  3340.  
  3341. PROCEDURE TFullTETypingCommand.FwdDelete(theText: Handle; curStart, curEnd: INTEGER);
  3342.  
  3343.     TYPE
  3344.         TSPtr                = ^TextStyle;
  3345.  
  3346.     VAR
  3347.         savedSize:            INTEGER;
  3348.         theHeight:            INTEGER;
  3349.         theAscent:            INTEGER;
  3350.         oldSize:            LONGINT;
  3351.         whoCares:            LONGINT;
  3352.         aTextStyle:         TSPtr;
  3353.         savedChar:            PACKED ARRAY [0..3] OF Char;
  3354.         delStyle:            TextStyle;
  3355.         delSubSuper:        SubOrSuper;
  3356.         delBaseSize:        INTEGER;
  3357.         textSize:            LONGINT;
  3358.         oldTextSize:        LONGINT;
  3359.  
  3360.     BEGIN
  3361.     textSize := GetHandleSize(theText);
  3362.     IF (curStart = curEnd) & (curStart < textSize) THEN
  3363.         BEGIN
  3364.  
  3365.         savedSize := 0;                                 {Get the complete character}
  3366.         IF qNeedsScriptManager | gConfiguration.hasScriptManager THEN
  3367.             WHILE (curStart + savedSize <= textSize) & (CharByte(theText^, curStart + savedSize) >
  3368.                   0) DO
  3369.                 savedSize := SUCC(savedSize);
  3370.         savedSize := savedSize + 1;
  3371.         {$IFC qDebug}
  3372.         IF savedSize > 4 THEN
  3373.             ProgramBreak('Character > 4 bytes');
  3374.         {$ENDC}
  3375.  
  3376.         IF savedSize = 1 THEN                            { Slight speed optimization for normal case
  3377.                                                          }
  3378.         {$Push} {$R-}
  3379.             savedChar[0] := CharsHandle(theText)^^[curStart]
  3380.             {$Pop}
  3381.         ELSE
  3382.             BlockMove(Ptr(ORD(theText^) + curStart), @savedChar, savedSize);
  3383.  
  3384.         IF (curStart >= fNewStart) & (curStart < fNewEnd) THEN { char is within fNewText }
  3385.             BEGIN                                        {Remove the char from fNewText and update
  3386.                                                          fNewEnd and fTextPad}
  3387.             SetHandleSize(fPadding, MAX( - (fTextPad - savedSize + fStylePad), 0));
  3388.             FailMemError;
  3389.             fNewEnd := fNewEnd - savedSize;
  3390.             fTextPad := fTextPad - savedSize;
  3391.  
  3392.             { Shouldn't fail as we're only shrinking it }
  3393.             whoCares := Munger(fNewText, curStart - fNewStart, NIL, savedSize, @savedChar, 0);
  3394.             FailMemError;
  3395.             END
  3396.         ELSE                                            { add char to the end of fOldChars, don't
  3397.                                                          update fOldEnd, but update fPadding }
  3398.             BEGIN                                        { why NOT update fOldEnd??? - DWG}
  3399.             oldTextSize := GetHandleSize(fOldText);
  3400.             IF fTEView.fStyleType = kWithStyle THEN     { Only do this if styles are around }
  3401.                 BEGIN
  3402.                 TEGetStyle(curStart, delStyle,            { Get the style of the deleted character }
  3403.                            theHeight, theAscent, fHTE); { (1 or 4 bytes, it's all only one style) }
  3404.  
  3405.                 IF NOT EqualBlocks(@delStyle,            { If style doesn't match last in the list }
  3406.                                    @fOldStyles^^.scrpStyleTab[fOldStyles^^.scrpNStyles -
  3407.                                    1].scrpFont, SIZEOF(TextStyle)) THEN
  3408.                     BEGIN                                { …then insert new style at end of list }
  3409.                     fTEView.fSpecsChanged := TRUE;        { User backspaced into new style! }
  3410.  
  3411.                     oldSize :=                            { Make room for the new style element }
  3412.                       GetHandleSize(Handle(fOldStyles));
  3413.                     SetHandleSize(Handle(fOldStyles), oldSize + SIZEOF(ScrpSTElement));
  3414.                     FailMemError;
  3415.                     fStylePad := fStylePad + SIZEOF(ScrpSTElement);
  3416.  
  3417.                     fOldStyles^^.scrpNStyles :=         { One more style }
  3418.                       SUCC(fOldStyles^^.scrpNStyles);
  3419.                       
  3420.                     WITH fOldStyles^^.scrpStyleTab[fOldStyles^^.scrpNStyles - 1] DO
  3421.                         BEGIN
  3422.                         scrpStartChar := oldTextSize;
  3423.                         scrpHeight := theHeight;        { Fill in the blanks }
  3424.                         scrpAscent := theAscent;
  3425.                         aTextStyle := TSPtr(@scrpFont);
  3426.                         aTextStyle^ := delStyle;
  3427.                         END;
  3428.                     END;
  3429.                 END;
  3430.  
  3431. {*******************************************************************************}
  3432.             IF TFullTEView(fTEView).fAllowSubSuper THEN 
  3433.                 BEGIN
  3434.                 TFullTEView(fTEView).GetSubSuper(curStart, delSubSuper, delBaseSize);
  3435.                 IF delSubSuper <> fOldSubSuper^^.runs[fOldSubSuper^^.nRuns - 1].subSuper THEN
  3436.                     BEGIN
  3437.                     fTEView.fSpecsChanged := TRUE;                { User backspaced into new sub/super! }
  3438.         
  3439.                     oldSize :=                                    { Make room for the new subsuper element }
  3440.                       GetHandleSize(Handle(fOldSubSuper));
  3441.                     SetHandleSize(Handle(fOldSubSuper), oldSize + SIZEOF(SubSuperElement));
  3442.                     FailMemError;
  3443.  
  3444.                     WITH fOldSubSuper^^ DO
  3445.                         BEGIN
  3446.                         nRuns := SUCC(nRuns);
  3447.                         runs[nRuns] := runs[nRuns - 1];
  3448.                         WITH runs[nRuns] DO
  3449.                             startChar := oldTextSize + savedSize;
  3450.                         END;
  3451.                     WITH fOldSubSuper^^.runs[fOldSubSuper^^.nRuns - 1] DO
  3452.                         BEGIN
  3453.                         startChar := oldTextSize;
  3454.                         subSuper := delSubSuper;
  3455.                         baseSize := delBaseSize;
  3456.                         END;
  3457.                     END;
  3458.                 END;
  3459. {*******************************************************************************}
  3460.  
  3461.             SetHandleSize(fPadding, oldTextSize + savedSize + fStylePad);
  3462.             FailMemError;
  3463.             whoCares := Munger(fOldText, oldTextSize, NIL, 0, @savedChar, savedSize);
  3464.             FailMemError;
  3465.             fTextPad := fTextPad - savedSize;
  3466.             
  3467.             fOldEnd := fOldEnd + savedSize;    { why not??? -DWG }
  3468.  
  3469.             END;
  3470.         END;
  3471.     END;
  3472.  
  3473. {--------------------------------------------------------------------------------------------------}
  3474. { ??? All this handle munging is expensive.  Better would be to accumulate memory in
  3475.   "chunks" of, say, 16 bytes so that this checking need not happen every time through.
  3476.   Fortunately, the normal cases are not that bad. }
  3477. {$S FullTERes}
  3478.  
  3479. PROCEDURE TFullTETypingCommand.AddCharacter(aChar: Char);
  3480.  
  3481.     VAR
  3482.         theText:            Handle;
  3483.         curSelStart:        INTEGER;
  3484.         curSelEnd:            INTEGER;
  3485.         savedPerm:            BOOLEAN;
  3486.         fi:                 FailInfo;
  3487.         index:                INTEGER;
  3488.         i:                    INTEGER;
  3489.  
  3490.     PROCEDURE HdlCharFailed(error: OSErr; message: LONGINT);
  3491.  
  3492.         BEGIN
  3493.         savedPerm := PermAllocation(savedPerm);
  3494.         END;
  3495.  
  3496.     BEGIN
  3497.     fView.Update;                                        { Makes sure that all of TE's actions are
  3498.                                                          Visible }
  3499.     IF fView.Focus THEN;
  3500.     WITH fHTE^^ DO                                        { Get handy info about the text handle }
  3501.         BEGIN
  3502.         curSelStart := selStart;
  3503.         curSelEnd := selEnd;
  3504.         theText := hText;
  3505.         END;
  3506.     CatchFailures(fi, HdlCharFailed);
  3507.     savedPerm := PermAllocation(TRUE);
  3508.  
  3509.  { Update the fNewText handle and other information.  Note that because of backspace,
  3510.   this can be tricky.}
  3511.  
  3512.     IF (aChar = chFwdDelete) THEN
  3513.         FwdDelete(theText, curSelStart, curSelEnd)        { User types forward delete, so keep in
  3514.                                                          synch}
  3515.  
  3516.     ELSE IF aChar <> chBackspace THEN                    { Not a backspace. Do the right thing }
  3517.         DoNormalChar(aChar)
  3518.  
  3519.     ELSE IF (curSelStart <= fOldStart) &                { User typed backspace so keep in synch }
  3520.             (curSelStart > 0) & (curSelStart = curSelEnd) THEN
  3521.         BkSpcLeft(theText, curSelStart)                 { Handle backspace to left of start }
  3522.  
  3523.     ELSE IF fNewEnd > fNewStart THEN                    { Delete 1 character from end of fNewText }
  3524.         BkSpcRight(theText, curSelStart);                { Handle backspace to right of start }
  3525.  
  3526.     savedPerm := PermAllocation(savedPerm);
  3527.     Success(fi);
  3528.  
  3529.     IF aChar <> chFwdDelete THEN
  3530.  { Let TextEdit have the character, as either 1) we're adding a byte, so we know there
  3531.   is a reserve tank, so the worst this will do is eat into it a little, or 2) we're
  3532.   deleting a character, which can only decrease memory usage. }
  3533.         BEGIN
  3534.         IF TFullTEView(fTEView).fAllowSubSuper THEN
  3535.             IF aChar = chBackspace THEN
  3536.                 { DeleteSubSuperChars will check for multi-byte characters... }
  3537.                 TFullTEView(fTEView).DeleteSubSuperChars(MIN(curSelStart, curSelEnd - 1), curSelEnd)
  3538.             ELSE
  3539.                 { If I'm reading everything correctly, a multi-byte character will still }
  3540.                 { only get to AddCharacter one byte at a time, so this should be okay... }
  3541.                 TFullTEView(fTEView).InsertSubSuperChars(curSelStart, 1, fNewSubSuper);
  3542.         TEKey(aChar, fHTE);
  3543.         END
  3544.     ELSE IF (curSelStart <> curSelEnd) THEN             { forward delete with chars selected}
  3545.         BEGIN
  3546.         IF TFullTEView(fTEView).fAllowSubSuper THEN
  3547.             TFullTEView(fTEView).DeleteSubSuperChars(curSelStart, curSelEnd);
  3548.         TEDelete(fHTE);
  3549.         END
  3550.     ELSE IF (curSelStart < GetHandleSize(theText)) THEN
  3551.         BEGIN                                            { forward delete with insertion point}
  3552.         TEKey(chRight, fHTE);
  3553.         IF TFullTEView(fTEView).fAllowSubSuper THEN
  3554.             { DeleteSubSuperChars will check for multi-byte characters... }
  3555.             TFullTEView(fTEView).DeleteSubSuperChars(curSelStart, curSelStart + 1);
  3556.         TEKey(chBackspace, fHTE);
  3557.         END;
  3558.  
  3559.     fTEView.SynchView(kRedraw);                         { Now clean up the view. }
  3560.  
  3561.     {$IFC qDebug}
  3562.     IF pTEIntenseDebugging THEN
  3563.         BEGIN
  3564.         WrLblHandleContents('fOldText', fOldText);
  3565.         WRITELN;
  3566.         WrLblHandleContents('fNewText', fNewText);
  3567.         WRITELN;
  3568.         DumpTTECommand(SELF);
  3569.         END;
  3570.     {$ENDC}
  3571.  
  3572.     END;
  3573.  
  3574. {--------------------------------------------------------------------------------------------------}
  3575. {$S FullTERes}
  3576.  
  3577. PROCEDURE TFullTETypingCommand.DoIt; OVERRIDE;
  3578.  
  3579. { no change from TTETypingCommand }
  3580.  
  3581.     BEGIN
  3582.     AddCharacter(fFirstChar);
  3583.     {$IFC qDebug}
  3584.     IF pTEIntenseDebugging THEN
  3585.         DumpTTECommand(SELF);
  3586.     {$ENDC}
  3587.     END;
  3588.  
  3589. {--------------------------------------------------------------------------------------------------}
  3590.  
  3591. {$S TEDoCommand}
  3592.  
  3593. PROCEDURE TFullTETypingCommand.RedoIt; OVERRIDE;
  3594.  
  3595.     VAR
  3596.         currentStyle:        TextStyle;
  3597.         lineHeight:            INTEGER;
  3598.         fontAscent:            INTEGER;
  3599.         resetStyle:            BOOLEAN;
  3600.         theSubSuper:        SubOrSuper;
  3601.         theBaseSize:        INTEGER;
  3602.         resetSubSuper:        BOOLEAN;
  3603.  
  3604.     BEGIN
  3605.     IF (fOldEnd - fOldStart) = GetHandleSize(fOldText) THEN
  3606.         BEGIN                                            { No chars were vacuumed}
  3607.         resetStyle := FALSE;
  3608.         IF (fTEView.fStyleType = kWithStyle) & (fOldEnd = fOldStart) THEN
  3609.             BEGIN
  3610.             TEGetStyle(fOldStart, currentStyle, lineHeight, fontAscent, fHTE);
  3611.             resetStyle := NOT EqualBlocks(@currentStyle, @fOldStyles^^.scrpStyleTab[0].scrpFont,
  3612.                                           SIZEOF(TextStyle));
  3613.             END;
  3614.  
  3615.         resetSubSuper := FALSE;
  3616.         IF (TFullTEView(fTEView).fAllowSubSuper) & (fOldEnd = fOldStart) THEN
  3617.             BEGIN
  3618.             TFullTEView(fTEView).GetSubSuper(fOldStart, theSubSuper, theBaseSize);
  3619.             resetSubSuper := (theSubSuper <> fOldSubSuper^^.runs[0].subSuper) |
  3620.                              (theBaseSize <> fOldSubSuper^^.runs[0].baseSize);
  3621.             END;
  3622.  
  3623.         IF resetStyle THEN                                { The new text has a style of its own }
  3624.             fNewStyles := fOldStyles;                    { Make InstallNewText insert styles, too }
  3625.         IF resetSubSuper THEN
  3626.             fNewSubSuper := fOldSubSuper;
  3627.  
  3628.         INHERITED RedoIt;
  3629.  
  3630.         IF resetStyle THEN
  3631.             fNewStyles := NIL;                            { So fNewStyles doesn't get disposed }
  3632.         IF resetSubSuper THEN
  3633.             fNewSubSuper := NIL;
  3634.  
  3635.         END
  3636.     ELSE
  3637.         BEGIN
  3638.         IF fTEView.Focus THEN;                            {??? What if Focus fails}
  3639.         TESetSelect(fOldStart,
  3640.                     fOldStart + GetHandleSize(fOldText), fHTE); { select vacuumed chars, too }
  3641.  
  3642.         TFullTEView(fTEView).DeleteSubSuperChars(fOldStart, fOldStart + GetHandleSize(fOldText));
  3643.  
  3644.         TEDelete(fHTE);                                 { Remove old text, including vacuumed chars}
  3645.         SetHandleSize(fPadding, MAX( - (fTextPad + fStylePad), 0));
  3646.         FailMemError;
  3647.         InstallNewText;
  3648.         fTEView.SynchView(kRedraw);
  3649.         {$IFC qDebug}
  3650.         IF pTEIntenseDebugging THEN
  3651.             DumpTTECommand(SELF);
  3652.         {$ENDC}
  3653.         END;
  3654.     END;
  3655.  
  3656. {--------------------------------------------------------------------------------------------------}
  3657. {$S TEDoCommand}
  3658.  
  3659. PROCEDURE TFullTETypingCommand.UndoIt; OVERRIDE;
  3660.  
  3661. { no changes from TTETypingCommand }
  3662.  
  3663.     BEGIN
  3664.     CompleteTyping;
  3665.     INHERITED UndoIt;
  3666.     END;
  3667.  
  3668. {--------------------------------------------------------------------------------------------------}
  3669. {$S FullTERes}
  3670.  
  3671. PROCEDURE TFullTETypingCommand.CompleteTyping;
  3672.  
  3673.     VAR
  3674.         i:                    INTEGER;
  3675.         offset:             LONGINT;
  3676.  
  3677.     BEGIN
  3678.     fCompleted := TRUE;
  3679.  
  3680.     IF fTEView.fStyleType = kWithStyle THEN
  3681.         WITH fOldStyles^^ DO
  3682.             BEGIN
  3683.             offset := - scrpStyleTab[0].scrpStartChar;
  3684.             IF offset > 0 THEN
  3685.                 FOR i := 0 TO scrpNStyles - 1 DO
  3686.                     scrpStyleTab[i].scrpStartChar := scrpStyleTab[i].scrpStartChar + offset;
  3687.             END;
  3688.     IF TFullTEView(fTEView).fAllowSubSuper THEN
  3689.         WITH fOldSubSuper^^ DO
  3690.             BEGIN
  3691.             offset := - runs[0].startChar;
  3692.             IF offset > 0 THEN
  3693.                 FOR i := 0 to nRuns DO
  3694.                     runs[i].startChar := runs[i].startChar + offset;
  3695.             END;
  3696.  
  3697.     {$IFC qDebug}
  3698.     IF pTEIntenseDebugging THEN
  3699.         DumpTTECommand(SELF);
  3700.     {$ENDC}
  3701.     END;
  3702.  
  3703. {--------------------------------------------------------------------------------------------------}
  3704. {$IFC qDebug}
  3705. {$S TEFields}
  3706.  
  3707. PROCEDURE TFullTETypingCommand.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  3708.                                                       fieldType: INTEGER)); OVERRIDE;
  3709.  
  3710. { no change from TTETypingCommand }
  3711.  
  3712.     BEGIN
  3713.     DoToField('TFullTETypingCommand', NIL, bClass);
  3714.     DoToField('fCompleted', @fCompleted, bBoolean);
  3715.     DoToField('fFirstChar', @fFirstChar, bBoolean);
  3716.     INHERITED Fields(DoToField);
  3717.     END;
  3718. {$ENDC}
  3719. {--------------------------------------------------------------------------------------------------}
  3720. {--------------------------------------------------------------------------------------------------}
  3721. {$S TESelCommand}
  3722.  
  3723. { No change from TTEStyleCommand }
  3724.  
  3725. PROCEDURE TFullTEStyleCommand.ITEStyleCommand(itsTEView: TTEView; itsNewStyle: TextStyle;
  3726.                                           itsCmdNumber: CmdNumber; itsMode: INTEGER);
  3727.  
  3728.     VAR
  3729.         savedPerm:            BOOLEAN;
  3730.         fi:                 FailInfo;
  3731.  
  3732.     BEGIN
  3733.  
  3734.     ITECommand(itsTEView, itsCmdNumber, FALSE);         { Perform stock initialization, sans text }
  3735.  
  3736.     fOldTextStyle := itsTEView.fTextStyle;
  3737.     fNewTextStyle := itsNewStyle;
  3738.  
  3739.     fMode := itsMode;
  3740.     IF qNeedsColorQD | gConfiguration.hasColorQD THEN
  3741.         fMode := itsMode
  3742.     ELSE
  3743.         fMode := BAND(itsMode, BNOT(doColor));
  3744.     END;
  3745.  
  3746. {--------------------------------------------------------------------------------------------------}
  3747. {$S TEDoCommand}
  3748.  
  3749. PROCEDURE TFullTEStyleCommand.InstallSubSuper(newSubSuper: SubSuperHandle);
  3750.  
  3751.     VAR        theStyle:        TextStyle;
  3752.             i:                INTEGER;
  3753.             theBaseSize:    INTEGER;
  3754.  
  3755.     BEGIN
  3756.     IF newSubSuper <> NIL THEN
  3757.         BEGIN
  3758.         TFullTEView(fTEView).SetSubSuper(fOldStart, fOldEnd, newSubSuper, kDontRedraw);
  3759.         MoveHHi(Handle(newSubSuper));
  3760.         HLock(Handle(newSubSuper));
  3761.         WITH newSubSuper^^ DO
  3762.             FOR i := 0 TO nRuns - 1 DO
  3763.                 WITH runs[i] DO
  3764.                     IF subSuper <> normal THEN
  3765.                         BEGIN
  3766.                         theBaseSize := baseSize;
  3767.                         IF theBaseSize = 0 THEN theBaseSize := GetDefFontSize;
  3768.                         theStyle.tsSize := theBaseSize DIV 2;
  3769.                         SetSelect(fOldStart + startChar,
  3770.                             fOldStart + MIN(runs[i + 1].startChar, runs[nRuns].startChar - 1), fHTE);
  3771.                         TESetStyle(doSize, theStyle, kDontRedraw, fHTE);
  3772.                         END;
  3773.         HUnlock(Handle(newSubSuper));
  3774.         END;
  3775.  
  3776.     SetSelect(fOldStart, fOldEnd, fHTE);
  3777.     END;
  3778.  
  3779. {--------------------------------------------------------------------------------------------------}
  3780. {$S TEDoCommand}
  3781.  
  3782. PROCEDURE TFullTEStyleCommand.InstallOneStyle(newStyl: TextStyle; newSubSuper: SubSuperHandle);
  3783.  
  3784.     VAR        aRect:    Rect;
  3785.     
  3786.     BEGIN
  3787.     fTEView.SetOneStyle(fOldStart, fOldEnd, fMode, newStyl, kDontRedraw); { Focus'es for us }
  3788.  
  3789.     IF TFullTEView(fTEView).fAllowSubSuper THEN
  3790.         InstallSubSuper(newSubSuper);
  3791.  
  3792.     fTEView.RecalcText;                                         { Might have changed number of lines }
  3793.     
  3794.     { and now, finally, we'll Redraw... }
  3795.     IF TFullTEView(fTEView).fAllowSubSuper THEN
  3796.         BEGIN
  3797.         fTEView.GetQDExtent(aRect);
  3798.         TEUpdate(aRect, fHTE);
  3799.         END;
  3800.     fTEView.SynchView(NOT TFullTEView(fTEView).fAllowSubSuper);
  3801.  
  3802.     fTEView.fSpecsChanged := TRUE;
  3803.     END;
  3804.  
  3805. {--------------------------------------------------------------------------------------------------}
  3806. {$S TEDoCommand}
  3807.  
  3808. PROCEDURE TFullTEStyleCommand.InstallManyStyles(newStyls: StScrpHandle; newSubSuper: SubSuperHandle);
  3809.  
  3810.     VAR        aRect:    Rect;
  3811.     
  3812.     BEGIN
  3813.     IF fTEView.Focus THEN;
  3814.  
  3815.     { No need to check for fStyleType, since we only get here if the record is stylish }
  3816.     SetStylScrap(fOldStart, fOldEnd, newStyls, kDontRedraw, fHTE);
  3817.  
  3818.     IF TFullTEView(fTEView).fAllowSubSuper THEN
  3819.         InstallSubSuper(newSubSuper);
  3820.  
  3821.     fTEView.RecalcText;                                         { Might have changed number of lines }
  3822.     
  3823.     { and now, finally, we'll Redraw... }
  3824.     IF TFullTEView(fTEView).fAllowSubSuper THEN
  3825.         BEGIN
  3826.         fTEView.GetQDExtent(aRect);
  3827.         TEUpdate(aRect, fHTE);
  3828.         END;
  3829.     fTEView.SynchView(NOT TFullTEView(fTEView).fAllowSubSuper);
  3830.  
  3831.     fTEView.fSpecsChanged := TRUE;
  3832.     END;
  3833.  
  3834. {--------------------------------------------------------------------------------------------------}
  3835. {$S TEDoCommand}
  3836.  
  3837. PROCEDURE TFullTEStyleCommand.DoIt; OVERRIDE;
  3838.  
  3839.     VAR
  3840.         aTextStyle:         TextStyle;
  3841.         aSubSuper:            SubSuperHandle;
  3842.         i:                    INTEGER;
  3843.         theBaseSize:        INTEGER;
  3844.  
  3845.     BEGIN
  3846.     aTextStyle := fNewTextStyle;
  3847.     aSubSuper := fNewSubSuper;
  3848.     IF aSubSuper = NIL THEN aSubSuper := fOldSubSuper;
  3849.     IF TFullTEView(fTEView).fAllowSubSuper & (fCmdNumber = cSizeChange) THEN
  3850.         BEGIN
  3851.         WITH aSubSuper^^ DO
  3852.             FOR i := 0 TO nRuns - 1 DO
  3853.                 IF BAND(fMode, doSize) <> 0 THEN
  3854.                     runs[i].baseSize := aTextStyle.tsSize
  3855.                 ELSE IF BAND(fMode, addSize) <> 0 THEN
  3856.                     BEGIN
  3857.                     theBaseSize := runs[i].baseSize;
  3858.                     if theBaseSize = 0 then theBaseSize := GetDefFontSize;
  3859.                     runs[i].baseSize := theBaseSize + aTextStyle.tsSize;
  3860.                     END;
  3861.         END;
  3862.     InstallOneStyle(aTextStyle, aSubSuper);
  3863.     fMode := BAND(fMode, BNOT(doToggle));                { Turn off toggle mode, if set }
  3864.     {$IFC qDebug}
  3865.     IF pTEIntenseDebugging THEN
  3866.         DumpTTECommand(SELF);
  3867.     {$ENDC}
  3868.     END;
  3869.  
  3870. {--------------------------------------------------------------------------------------------------}
  3871. {$S TEDoCommand}
  3872.  
  3873. PROCEDURE TFullTEStyleCommand.UndoIt; OVERRIDE;
  3874.  
  3875.     VAR
  3876.         aTextStyle:         TextStyle;
  3877.  
  3878.     BEGIN
  3879.     RestoreSelection;
  3880.  
  3881.     IF fTEView.fStyleType = kWithoutStyle THEN
  3882.         BEGIN
  3883.         aTextStyle := fOldTextStyle;
  3884.         InstallOneStyle(aTextStyle, fOldSubSuper)
  3885.         END
  3886.     ELSE
  3887.         InstallManyStyles(fOldStyles, fOldSubSuper);
  3888.     {$IFC qDebug}
  3889.     IF pTEIntenseDebugging THEN
  3890.         DumpTTECommand(SELF);
  3891.     {$ENDC}
  3892.     END;
  3893.  
  3894. {--------------------------------------------------------------------------------------------------}
  3895. {$S TEDoCommand}
  3896.  
  3897. { No change from TTEStyleCommand }
  3898.  
  3899. PROCEDURE TFullTEStyleCommand.RedoIt; OVERRIDE;
  3900.  
  3901.     BEGIN
  3902.     RestoreSelection;
  3903.     DoIt;
  3904.     END;
  3905.  
  3906. {--------------------------------------------------------------------------------------------------}
  3907. {$IFC qDebug}
  3908. {$S TEFields}
  3909.  
  3910. { No change from TTEStyleCommand }
  3911.  
  3912. PROCEDURE TFullTEStyleCommand.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  3913.                                                      fieldType: INTEGER)); OVERRIDE;
  3914.  
  3915.     BEGIN
  3916.     DoToField('TFullTEStyleCommand', NIL, bClass);
  3917.     DoToField('fMode', @fMode, bInteger);
  3918.     {$Push} {$H-}
  3919.     TextStyleFields('fOldTextStyle', fOldTextStyle, DoToField);
  3920.     TextStyleFields('fNewTextStyle', fNewTextStyle, DoToField);
  3921.     {$Pop}
  3922.     INHERITED Fields(DoToField);
  3923.     END;
  3924.  
  3925. {$ENDC}
  3926. {--------------------------------------------------------------------------------------------------}
  3927. {--------------------------------------------------------------------------------------------------}
  3928. {$S TESelCommand}
  3929.  
  3930. PROCEDURE TFullTESubSuperCommand.ITFullTESubSuperCommand(itsTEView: TFullTEView; itsCmdNumber: CmdNumber);
  3931.  
  3932.     VAR        aSubSuperHandle:        SubSuperHandle;
  3933.             oldStyles:                StScrpHandle;
  3934.             which, oldWhich:        SubOrSuper;
  3935.             i:                        INTEGER;
  3936.             theBaseSize:            INTEGER;
  3937.             newStyle:                TextStyle;
  3938.             mode:                    INTEGER;
  3939.             startOfSelection:        INTEGER;
  3940.             endOfSelection:            INTEGER;
  3941.     
  3942.     BEGIN
  3943.     
  3944.     aSubSuperHandle := itsTEView.GetSubSuperHandle;
  3945.     FailNIL(aSubSuperHandle);
  3946.     
  3947.     WITH itsTEView.fHTE^^ DO
  3948.         BEGIN
  3949.         startOfSelection := selStart;
  3950.         endOfSelection := selEnd;
  3951.         END;
  3952.     
  3953.     if itsCmdNumber = cSubscript then
  3954.         which := subscript
  3955.     else if itsCmdNumber = cSuperscript then
  3956.         which := superscript
  3957.     else
  3958.         which := normal;
  3959.         
  3960.     if which <> normal then
  3961.         if itsTEView.ContinuousSubSuper(startOfSelection, endOfSelection, oldWhich, theBaseSize)
  3962.                      & (oldWhich = which) then
  3963.             which := normal            { toggle sub/superscript back to normal }
  3964.         else
  3965.             oldWhich := undefined
  3966.     else
  3967.         oldWhich := undefined;
  3968.  
  3969.     if oldWhich = undefined then
  3970.         BEGIN
  3971.         theBaseSize := 0;
  3972.         oldStyles := GetStylScrap(itsTEView.fHTE);
  3973.         FailNIL(oldStyles);
  3974.         WITH oldStyles^^ DO
  3975.             FOR i := 0 TO scrpNStyles - 1 DO
  3976.                 theBaseSize := MAX(scrpStyleTab[i].scrpSize , theBaseSize);
  3977.         DisposHandle(Handle(oldStyles));
  3978.         WITH aSubSuperHandle^^ DO
  3979.             FOR i := 0 TO nRuns - 1 DO
  3980.                 theBaseSize := MAX(runs[i].baseSize, theBaseSize);
  3981.         if theBaseSize = 0 then theBaseSize := GetDefFontSize;
  3982.         END
  3983.     else
  3984.         theBaseSize := itsTEView.fSubSuperHandle^^.runs[
  3985.                         GetIndex(itsTEView.fSubSuperHandle, startOfSelection)].baseSize;
  3986.  
  3987.     if which = normal then
  3988.         newStyle.tsSize := theBaseSize
  3989.     else    
  3990.         newStyle.tsSize := theBaseSize DIV 2;
  3991.         
  3992.     if itsCmdNumber = cPlainText then
  3993.         BEGIN
  3994.         newStyle.tsFace := [];
  3995.         mode := doSize + doFace;
  3996.         END
  3997.     else
  3998.         mode := doSize;
  3999.     
  4000.     ITEStyleCommand(itsTEView, newStyle, cStyleChange, mode);
  4001.         
  4002.     fNewSubSuper := aSubSuperHandle;
  4003.         
  4004.     WITH fNewSubSuper^^ DO
  4005.         FOR i := 0 TO nRuns - 1 DO
  4006.             BEGIN
  4007.             runs[i].subSuper := which;
  4008.             runs[i].baseSize := theBaseSize;
  4009.             END;
  4010.     
  4011.     END;
  4012.  
  4013. {--------------------------------------------------------------------------------------------------}
  4014. {$IFC qDebug}
  4015. {$S TEFields}
  4016.  
  4017. PROCEDURE TFullTESubSuperCommand.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  4018.                                                      fieldType: INTEGER)); OVERRIDE;
  4019.  
  4020.     BEGIN
  4021.     DoToField('TTFullTESubSuperCommand', NIL, bClass);
  4022.     INHERITED Fields(DoToField);
  4023.     END;
  4024. {$ENDC}
  4025. {--------------------------------------------------------------------------------------------------}
  4026. {$ENDC}
  4027. {--------------------------------------------------------------------------------------------------}
  4028. {--------------------------------------------------------------------------------------------------}
  4029.